class Player(QDialog): def __init__(self): super().__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) # self.show() self.ui.btn_play.clicked.connect(self.playvideo) #включить видео self.ui.btn_stop.clicked.connect(self.stopvideo) #остановить видео self.ui.btn_pause.clicked.connect(self.pausevideo) #пауза self.ui.btn_back.clicked.connect(self.hidewindow) #скрыть окно плеера self.ui.verticalSlider.valueChanged.connect(self.setvolume) #громкость # self.ui.horizontalSlider.valueChanged.connect(self.settimevideo) #перемотка - починить функцию self.ui.listWidget.addItems(listdir("records")) #генерация списка файлов в папке records self.ui.listWidget.itemClicked.connect(self.playthis) #выбор видео self.player = QMediaPlayer() self.player.positionChanged.connect(self.setvideoonslider)#автодвижение ползунка self.video = QVideoWidget(self.ui.label) self.video.resize(621, 451) self.video.move(0, 0) self.player.setVideoOutput(self.video) self.video.show() self.ui.label.customContextMenuRequested.connect(self.testfun) #ПРАВАЯ КНОПКА МЫШИ def testfun(self): print("Тест успешен") def playvideo(self): self.player.play() self.ui.horizontalSlider.setMaximum(self.player.duration()) self.ui.horizontalSlider.setPageStep(self.player.duration() / 10) def stopvideo(self): self.player.stop() def pausevideo(self): self.player.pause() def hidewindow(self): self.hide() def setvolume(self): self.player.setVolume(self.ui.verticalSlider.value()) def settimevideo(self): self.player.setPosition(self.ui.horizontalSlider.value()) def playthis(self): self.player.setMedia(QMediaContent(QUrl.fromLocalFile("records/" + str(self.ui.listWidget.currentItem().text())))) def setvideoonslider(self): self.ui.horizontalSlider.setValue(self.player.position()) self.ui.lbl_time.setText(str(int(self.player.position() / 1000)) + "/" + str(int(self.player.duration() / 1000))) def test(self): print("Тест пройден")
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 VideoPlayerWithControls( QWidget ): def __init__( self ): super().__init__() self.video_w = QVideoWidget() self.v_player = QMediaPlayer( None, QMediaPlayer.VideoSurface ) self.v_player.setVideoOutput( self.video_w ) self.v_player.setNotifyInterval( 50 ) self.v_player.stateChanged.connect( self.video_ended ) self.controls = VideoControls( self.v_player ) self._layout = QVBoxLayout() self._layout.addWidget( self.video_w ) self._layout.addWidget( self.controls ) self._layout.setSpacing( 0 ) self._layout.setContentsMargins( 0, 0, 0, 0 ) self.setLayout( self._layout ) def video_ended( self, state ): if state == QMediaPlayer.StoppedState: self.v_player.setPosition( self.v_player.duration() - 10 ) self.v_player.play() self.v_player.pause()
class QMediaPlayerAdapter(Player): def __init__(self, interval=1): self.__callback = None self.__player = QMediaPlayer() self.setNotifyInterval(interval) def setNotifyInterval(self, interval): self.__player.setNotifyInterval(interval) def setMusicPath(self, filePath): qUrl = QUrl(filePath) self.__player.setMedia(QMediaContent(qUrl)) def getState(self): return self.__player.state() def getStatus(self): return self.__player.mediaStatus() def getPosition(self): return self.__player.position() def getDuration(self): return self.__player.duration() def start(self): if self.__player.state() != QMediaPlayer.NoMedia: self.__player.play() # self.__player.setPosition(self.__player.duration() - 2000) else: raise ValueError( "The media of the player should be set before the player get started." ) def pause(self): self.__player.pause() def stop(self): self.__player.stop() def setCallback(self, callback): '''if not isinstance(callback, PlayerCallback): raise TypeError("The callback should be instance of PlayerCallback.")''' self.__callback = callback self.__player.mediaStatusChanged.connect( self.__callback.onMediaStatusChanged) self.__player.stateChanged.connect(self.__callback.onStateChanged) self.__player.positionChanged.connect( self.__callback.onPlayerPositionChanged)
class videoPlayer(QWidget): # 视频播放类 def __init__(self, parent=None): # 构造函数 super(videoPlayer, self).__init__(parent=parent) # 类的继承 self.mainwindow = parent self.length = 0 # 视频总时长 self.position = 0 # 视频当前时长 self.count = 0 self.player_status = -1 # 设置窗口 self.setGeometry(300, 50, 800, 600) #大小,与桌面放置位置 # self.setWindowIcon(QIcon(':/images/video_player_icon.png')) # 程序图标 # self.setWindowTitle(titleName) # 窗口名称 # self.setWindowFlags(Qt.WindowCloseButtonHint | Qt.WindowMinimizeButtonHint) # 设置窗口背景 self.palette = QPalette() self.palette.setColor(QPalette.Background, Qt.black) self.setPalette(self.palette) self.now_position = QLabel("/ 00:00") # 目前时间进度 self.all_duration = QLabel('00:00') # 总的时间进度 self.all_duration.setStyleSheet('''QLabel{color:#000000}''') self.now_position.setStyleSheet('''QLabel{color:#000000}''') #视频插件 self.video_widget = QVideoWidget(self) self.video_widget.setGeometry(QRect(0, 0, 1200, 700)) #大小,与桌面放置位置 #self.video_widget.resize(1200, 700) # 设置插件宽度与高度 #self.video_widget.move(0, 30) # 设置插件放置位置 self.video_palette = QPalette() self.video_palette.setColor(QPalette.Background, Qt.black) # 设置播放器背景 self.video_widget.setPalette(self.video_palette) video_widget_color = "background-color:#000000" self.video_widget.setStyleSheet(video_widget_color) #布局容器 self.verticalLayout = QVBoxLayout() self.verticalLayout.setSpacing(0) #self.verticalLayout.setContentsMargins(0, 5, 0, 10) self.layout = QHBoxLayout() self.layout.setSpacing(15) # 各个插件的间距 # 设置播放器 self.player = QMediaPlayer(self) self.player.setVideoOutput(self.video_widget) #设置播放按钮事件 self.player.durationChanged.connect(self.get_duration_func) # self.player.positionChanged.connect(self.progress) # 媒体播放时发出信号 self.player.mediaStatusChanged.connect(self.playerStatusChanged) self.player.error.connect(self.player_error) # 播放按钮 self.play_btn = QPushButton(self) self.play_btn.setIcon(QIcon(':/images/play_btn_icon.png')) # 设置按钮图标,下同 self.play_btn.setIconSize(QSize(35, 35)) self.play_btn.setStyleSheet( '''QPushButton{border:none;}QPushButton:hover{border:none;border-radius:35px;}''' ) self.play_btn.setCursor(QCursor(Qt.PointingHandCursor)) self.play_btn.setToolTip("播放") self.play_btn.setFlat(True) #self.play_btn.hide() #isHidden() #判定控件是否隐藏 #isVisible() 判定控件是否显示 self.play_btn.clicked.connect(self.start_button) #音量条 self.volume_slider = QSlider(Qt.Horizontal) # 声音设置 self.volume_slider.setMinimum(0) # 音量0到100 self.volume_slider.setMaximum(100) self.volume_slider.valueChanged.connect(self.volumes_change) self.volume_slider.setStyleSheet('''QSlider{} QSlider::sub-page:horizontal:disabled{background: #00009C; border-color: #999; } QSlider::add-page:horizontal:disabled{background: #eee; border-color: #999; } QSlider::handle:horizontal:disabled{background: #eee; border: 1px solid #aaa; border-radius: 4px; } QSlider::add-page:horizontal{background: #575757; border: 0px solid #777; height: 10px;border-radius: 2px; } QSlider::handle:horizontal:hover{background:qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0.6 #2A8BDA, stop:0.778409 rgba(255, 255, 255, 255)); width: 11px; margin-top: -3px; margin-bottom: -3px; border-radius: 5px; } QSlider::sub-page:horizontal{background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #B1B1B1, stop:1 #c4c4c4); background: qlineargradient(x1: 0, y1: 0.2, x2: 1, y2: 1,stop: 0 #5DCCFF, stop: 1 #1874CD); border: 1px solid #4A708B; height: 10px; border-radius: 2px; } QSlider::groove:horizontal{border: 1px solid #4A708B; background: #C0C0C0; height: 5px; border-radius: 1px; padding-left:-1px; padding-right:-1px;} QSlider::handle:horizontal{background: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0.6 #45ADED, stop:0.778409 rgba(255, 255, 255, 255)); width: 11px; margin-top: -3px; margin-bottom: -3px; border-radius: 5px; }''' ) #视频播放进度条 self.video_slider = QSlider(Qt.Horizontal, self) # 视频进度拖拖动 self.video_slider.setMinimum(0) # 视频进度0到100% #self.video_slider.setMaximum(100) self.video_slider.setSingleStep(1) self.video_slider.setGeometry(QRect(0, 0, 200, 10)) self.video_slider.sliderReleased.connect(self.video_silder_released) self.video_slider.sliderPressed.connect(self.video_silder_pressed) self.video_slider.setStyleSheet('''QSlider{} QSlider::sub-page:horizontal:disabled{background: #00009C; border-color: #999; } QSlider::add-page:horizontal:disabled{background: #eee; border-color: #999; } QSlider::handle:horizontal:disabled{background: #eee; border: 1px solid #aaa; border-radius: 4px; } QSlider::add-page:horizontal{background: #575757; border: 0px solid #777; height: 10px;border-radius: 2px; } QSlider::handle:horizontal:hover{background:qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0.6 #2A8BDA, stop:0.778409 rgba(255, 255, 255, 255)); width: 11px; margin-top: -3px; margin-bottom: -3px; border-radius: 5px; } QSlider::sub-page:horizontal{background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #B1B1B1, stop:1 #c4c4c4); background: qlineargradient(x1: 0, y1: 0.2, x2: 1, y2: 1,stop: 0 #5DCCFF, stop: 1 #1874CD); border: 1px solid #4A708B; height: 10px; border-radius: 2px; } QSlider::groove:horizontal{border: 1px solid #4A708B; background: #C0C0C0; height: 5px; border-radius: 1px; padding-left:-1px; padding-right:-1px;} QSlider::handle:horizontal{background: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0.6 #45ADED, stop:0.778409 rgba(255, 255, 255, 255)); width: 11px; margin-top: -3px; margin-bottom: -3px; border-radius: 5px; }''' ) #静音按钮 self.mute_button = QPushButton('') self.mute_button.clicked.connect(self.mute) self.mute_button.setIconSize(QSize(30, 30)) self.mute_button.setStyleSheet( '''QPushButton{border:none;}QPushButton:hover{border:none;}''') self.mute_button.setCursor(QCursor(Qt.PointingHandCursor)) self.mute_button.setToolTip("播放") self.mute_button.setFlat(True) self.mute_button.setIcon(QIcon(':/images/sound_btn_icon.png')) #暂停按钮 self.pause_btn = QPushButton('') self.pause_btn.setIcon(QIcon(':/images/stop_btn_icon.png')) self.pause_btn.clicked.connect(self.stop_button) self.pause_btn.setIconSize(QSize(35, 35)) self.pause_btn.setStyleSheet( '''QPushButton{border:none;}QPushButton:hover{border:none;}''') self.pause_btn.setCursor(QCursor(Qt.PointingHandCursor)) self.pause_btn.setToolTip("播放") self.pause_btn.setFlat(True) self.pause_btn.hide() #音量值和音量显示标签 self.volume_value = QLabel() self.volume_value.setText(' ' * 5) self.volume_value.setStyleSheet('''QLabel{color:#000000;}''') self.volume_t = QLabel() self.volume_t.setStyleSheet('''QLabel{color:#000000;}''') #视频文件打开按钮 self.open_btn = QPushButton('Open') self.open_btn.clicked.connect(self.getfile) #全屏按钮 self.screen_btn = QPushButton('') self.screen_btn.setIcon( QIcon(QPixmap(':/images/fullsrceen_btn_icon.png'))) self.screen_btn.setIconSize(QSize(38, 38)) self.screen_btn.setStyleSheet( '''QPushButton{border:none;}QPushButton:hover{border:1px solid #F3F3F5;border-radius:35px;}''' ) self.screen_btn.setCursor(QCursor(Qt.PointingHandCursor)) self.screen_btn.setToolTip("播放") self.screen_btn.setFlat(True) self.screen_btn.clicked.connect(self.fullscreen) #添加按钮组件 self.verticalLayout.addStretch() self.layout.addWidget(self.play_btn, 0, Qt.AlignCenter | Qt.AlignVCenter) self.layout.addWidget(self.pause_btn, 0, Qt.AlignCenter | Qt.AlignVCenter) # 插件,与前一个模块的距离,位置 self.layout.addWidget(self.all_duration, 0, Qt.AlignCenter | Qt.AlignVCenter) self.layout.addWidget(self.now_position, 0, Qt.AlignCenter | Qt.AlignVCenter) self.layout.addWidget(self.video_slider, 15, Qt.AlignVCenter | Qt.AlignVCenter) self.layout.addWidget(self.mute_button, 0, Qt.AlignCenter | Qt.AlignVCenter) self.layout.addWidget(self.volume_slider, 0, Qt.AlignCenter | Qt.AlignVCenter) self.layout.addWidget(self.volume_value, 0, Qt.AlignCenter | Qt.AlignVCenter) #self.layout.addWidget(self.screen_btn) #self.layout.addWidget(self.open_btn) self.verticalLayout.addLayout(self.layout) #self.verticalLayout.addLayout(self.layout) self.setLayout(self.verticalLayout) def player_error(self, errorCode): print('error = ' + str(errorCode)) try: if errorCode == 0: pass elif errorCode == 1: self.showAlertWindow('errorCode:1 \n\n无效视频源。') elif errorCode == 2: self.showAlertWindow('errorCode:2 \n\n不支持的媒体格式') elif errorCode == 3: self.showAlertWindow('errorCode:3 \n\n网络错误') elif errorCode == 4: self.showAlertWindow('errorCode:4 \n\n没有权限播放该视频') elif errorCode == 5: self.showAlertWindow('errorCode:5 \n\n视频服务不存在,无法继续播放。') else: self.showAlertWindow('未知错误') except: self.showAlertWindow('视频加载异常') def video_silder_pressed(self): if self.player.state != 0: self.player.pause() def playerStatusChanged(self, status): self.player_status = status if status == 7: self.play_btn.show() self.pause_btn.hide() #print('playerStatusChanged =' + str(status) + '...............') def resizeEvent(self, e): #print(e.size().width(), e.size().height()) newSize = e.size() self.video_widget.setGeometry(0, 0, newSize.width(), newSize.height() - 50) #self.video_widget.setGeometry(0, 0, 0, 0) def closeEvent(self, e): self.player.stop() def get_duration_func(self, d): try: end_number = int(d / 1000 / 10) + 1 #print('end_number = ' + str(end_number)) sum = 0 for n in range(1, end_number): sum = sum + n vv = int((100 / (d / 1000)) * (d / 1000)) self.video_slider.setMaximum(d) #self.video_slider.setMaximum(vv + sum) #print(100 + sum) all_second = int(d / 1000 % 60) # 视频播放时间 all_minute = int(d / 1000 / 60) if all_minute < 10: if all_second < 10: self.all_duration.setText('0' + str(all_minute) + ':0' + str(all_second)) else: self.all_duration.setText('0' + str(all_minute) + ':' + str(all_second)) else: if all_second < 10: self.all_duration.setText( str(all_minute) + ':0' + str(all_second)) else: self.all_duration.setText( str(all_minute) + ':' + str(all_second)) except Exception as e: pass def mouseDoubleClickEvent(self, e): try: #print('mouseDoubleClickEvent................... = ' + str(self.player.state())) if self.player.state() == 2: #视频暂停 self.player.play() self.play_btn.hide() self.pause_btn.show() elif self.player.state() == 1: # 正在播放 self.player.pause() self.play_btn.show() self.pause_btn.hide() else: #视频停止 self.play_btn.hide() self.pause_btn.show() self.player.setPosition(0) self.video_slider.setValue(0) self.player.play() except Exception as e: pass def start_button(self): # 视频播放按钮 try: self.play_btn.hide() self.pause_btn.show() if self.player_status == 7: self.video_slider.setValue(0) self.player.setPosition(0) self.player.play() except Exception as e: pass def stop_button(self): # 视频暂停按钮 self.play_btn.show() self.pause_btn.hide() self.player.pause() def getfile(self, filepath): # 打开视频文件 try: #print(str(filepath)) url = QUrl.fromLocalFile(filepath) if url.isValid(): self.player.setMedia(QMediaContent(url)) # 返回该文件地址,并把地址放入播放内容中 self.player.setVolume(50) # 设置默认打开音量即为音量条大小 self.volume_value.setText(str(50)) self.volume_slider.setValue(50) else: self.showAlertWindow('视频地址无效') except Exception as e: self.showAlertWindow() def clearVolumeValue(): self.volume_value.setText(' ' * 5) def volumes_change(self): # 拖动进度条设置声音 try: size = self.volume_slider.value() if size: # 但进度条的值不为0时,此时音量不为静音,音量值即为进度条值 self.player.setMuted(False) self.player.setVolume(size) volume_value = str(size) + ' ' * 4 self.volume_value.setText(volume_value) #print(size) self.mute_button.setIcon(QIcon(':/images/sound_btn_icon.png')) else: self.player.setMuted(True) self.mute_button.setIcon(QIcon(':/images/mute_btn_icon.png')) self.player.setVolume(0) volume_value = '0' + ' ' * 4 self.volume_value.setText(volume_value) if len(str(size)) == 1: volume_value = str(size) + ' ' * 4 elif len(str(size)) == 2: volume_value = str(size) + ' ' * 3 else: volume_value = str(size) + ' ' * 2 self.volume_value.setText(volume_value) except Exception as e: pass def mute(self): try: if self.player.isMuted(): self.mute_button.setIcon(QIcon(':/images/sound_btn_icon.png')) self.player.setMuted(False) self.volume_slider.setValue(50) volume_value = '50' + ' ' * 4 self.volume_value.setText(volume_value) else: self.mute_button.setIcon(QIcon(':/images/mute_btn_icon.png')) self.player.setMuted(True) # 若不为静音,则设置为静音,音量置为0 self.volume_slider.setValue(0) volume_value = '0' + ' ' * 4 self.volume_value.setText(volume_value) except Exception as e: pass def progress(self): # 视频进度条自动释放与播放时间 try: self.length = self.player.duration() + 1 self.position = self.player.position() #print(str(self.length) + ':' + str(self.position)) self.count += 1 video_silder_maximum = self.video_slider.maximum() #video_silder_value = int(((video_silder_maximum / (self.length / 1000)) * (self.position / 1000))) #self.video_slider.setValue(video_silder_value + self.count) self.video_slider.setValue(self.position) #print('video_slider_value = ' + str(video_silder_value + self.count)) now_second = int(self.position / 1000 % 60) now_minute = int(self.position / 1000 / 60) self.mainwindow.resultlist2.addItem("{0:02d} : {1:02d}".format( now_minute, now_second)) #print(str(now_minute) + ':' + str(now_second)) if now_minute < 10: if now_second < 10: self.now_position.setText('/ 0' + str(now_minute) + ':0' + str(now_second)) else: self.now_position.setText('/ 0' + str(now_minute) + ':' + str(now_second)) else: #print('now_minute < 10' + str(now_minute) + ':' + str(now_second)) if now_second < 10: #print('now_second < 10' + str(now_minute) + ':' + str(now_second)) #self.now_position.setText(str(now_minute) + ':0' + str(now_second)) self.now_position.setText('/ ' + str(now_minute) + ':0' + str(now_second)) else: #print('now_second > 10' + str(now_minute) + ':' + str(now_second)) self.now_position.setText('/ ' + str(now_minute) + ':' + str(now_second)) except Exception as e: pass def video_silder_released(self): # 释放滑条时,改变视频播放进度 try: #print('video_silder_released......') if self.player.state() != 0: self.player.setPosition(self.video_slider.value()) self.player.play() else: #如果视频是停止状态,则拖动进度条无效 self.video_slider.setValue(0) except Exception as e: pass def fullscreen(self): self.showFullScreen() def keyPressEvent(self, event): # 重新改写按键 if event.key() == Qt.Key_Escape: self.winquit() def winquit(self): # 退出窗口 self.showNormal() def showAlertWindow(self, msg='视频加载出错!'): reply = QMessageBox.information(self, "消息框标题", msg, QMessageBox.Yes) def setWindowTitleName(self, titleName): self.setWindowTitle(titleName) # 窗口名称
class Player(QWidget): fullScreenChanged = pyqtSignal(bool) def __init__(self, playlist, parent=None): super(Player, self).__init__(parent) self.colorDialog = None self.trackInfo = "" self.statusInfo = "" self.duration = 0 self.player = QMediaPlayer() self.playlist = QMediaPlaylist() self.player.setPlaylist(self.playlist) self.player.durationChanged.connect(self.durationChanged) self.player.positionChanged.connect(self.positionChanged) self.player.metaDataChanged.connect(self.metaDataChanged) self.playlist.currentIndexChanged.connect(self.playlistPositionChanged) self.player.mediaStatusChanged.connect(self.statusChanged) self.player.bufferStatusChanged.connect(self.bufferingProgress) self.player.videoAvailableChanged.connect(self.videoAvailableChanged) self.player.error.connect(self.displayErrorMessage) self.videoWidget = VideoWidget() self.player.setVideoOutput(self.videoWidget) self.playlistModel = PlaylistModel() self.playlistModel.setPlaylist(self.playlist) self.playlistView = QListView() self.playlistView.setModel(self.playlistModel) self.playlistView.setCurrentIndex( self.playlistModel.index(self.playlist.currentIndex(), 0)) self.playlistView.activated.connect(self.jump) self.slider = QSlider(Qt.Horizontal) self.slider.setRange(0, self.player.duration() / 1000) self.labelDuration = QLabel() self.slider.sliderMoved.connect(self.seek) # self.labelHistogram = QLabel() # self.labelHistogram.setText("Histogram:") # self.histogram = HistogramWidget() # histogramLayout = QHBoxLayout() # histogramLayout.addWidget(self.labelHistogram) # histogramLayout.addWidget(self.histogram, 1) self.probe = QVideoProbe() # self.probe.videoFrameProbed.connect(self.histogram.processFrame) self.probe.setSource(self.player) openButton = QPushButton("打开", clicked=self.open) controls = PlayerControls() controls.setState(self.player.state()) controls.setVolume(self.player.volume()) controls.setMuted(controls.isMuted()) controls.play.connect(self.player.play) controls.pause.connect(self.player.pause) controls.stop.connect(self.player.stop) controls.next.connect(self.playlist.next) controls.previous.connect(self.previousClicked) controls.changeVolume.connect(self.player.setVolume) controls.changeMuting.connect(self.player.setMuted) controls.changeRate.connect(self.player.setPlaybackRate) controls.stop.connect(self.videoWidget.update) self.player.stateChanged.connect(controls.setState) self.player.volumeChanged.connect(controls.setVolume) self.player.mutedChanged.connect(controls.setMuted) self.fullScreenButton = QPushButton("全屏") self.fullScreenButton.setCheckable(True) self.colorButton = QPushButton("颜色选项") self.colorButton.setEnabled(False) self.colorButton.clicked.connect(self.showColorDialog) displayLayout = QHBoxLayout() displayLayout.addWidget(self.videoWidget, 2) displayLayout.addWidget(self.playlistView) controlLayout = QHBoxLayout() controlLayout.setContentsMargins(0, 0, 0, 0) controlLayout.addWidget(openButton) controlLayout.addStretch(1) controlLayout.addWidget(controls) controlLayout.addStretch(1) controlLayout.addWidget(self.fullScreenButton) controlLayout.addWidget(self.colorButton) layout = QVBoxLayout() layout.addLayout(displayLayout) hLayout = QHBoxLayout() hLayout.addWidget(self.slider) hLayout.addWidget(self.labelDuration) layout.addLayout(hLayout) layout.addLayout(controlLayout) # layout.addLayout(histogramLayout) self.setLayout(layout) if not self.player.isAvailable(): QMessageBox.warning( self, "Service not available", "The QMediaPlayer object does not have a valid service.\n" "Please check the media service plugins are installed.") controls.setEnabled(False) self.playlistView.setEnabled(False) openButton.setEnabled(False) self.colorButton.setEnabled(False) self.fullScreenButton.setEnabled(False) self.metaDataChanged() self.addToPlaylist(playlist) def open(self): fileNames, _ = QFileDialog.getOpenFileNames(self, "Open Files") self.addToPlaylist(fileNames) def addToPlaylist(self, fileNames): for name in fileNames: fileInfo = QFileInfo(name) if fileInfo.exists(): url = QUrl.fromLocalFile(fileInfo.absoluteFilePath()) if fileInfo.suffix().lower() == 'm3u': self.playlist.load(url) else: self.playlist.addMedia(QMediaContent(url)) else: url = QUrl(name) if url.isValid(): self.playlist.addMedia(QMediaContent(url)) def durationChanged(self, duration): duration /= 1000 self.duration = duration self.slider.setMaximum(duration) def positionChanged(self, progress): progress /= 1000 if not self.slider.isSliderDown(): self.slider.setValue(progress) self.updateDurationInfo(progress) def metaDataChanged(self): if self.player.isMetaDataAvailable(): self.setTrackInfo( "%s - %s" % (self.player.metaData(QMediaMetaData.AlbumArtist), self.player.metaData(QMediaMetaData.Title))) def previousClicked(self): # Go to the previous track if we are within the first 5 seconds of # playback. Otherwise, seek to the beginning. if self.player.position() <= 5000: self.playlist.previous() else: self.player.setPosition(0) def jump(self, index): if index.isValid(): self.playlist.setCurrentIndex(index.row()) self.player.play() def playlistPositionChanged(self, position): self.playlistView.setCurrentIndex(self.playlistModel.index( position, 0)) def seek(self, seconds): self.player.setPosition(seconds * 1000) def statusChanged(self, status): self.handleCursor(status) if status == QMediaPlayer.LoadingMedia: self.setStatusInfo("Loading...") elif status == QMediaPlayer.StalledMedia: self.setStatusInfo("Media Stalled") elif status == QMediaPlayer.EndOfMedia: QApplication.alert(self) elif status == QMediaPlayer.InvalidMedia: self.displayErrorMessage() else: self.setStatusInfo("") def handleCursor(self, status): if status in (QMediaPlayer.LoadingMedia, QMediaPlayer.BufferingMedia, QMediaPlayer.StalledMedia): self.setCursor(Qt.BusyCursor) else: self.unsetCursor() def bufferingProgress(self, progress): self.setStatusInfo("Buffering %d%" % progress) def videoAvailableChanged(self, available): if available: self.fullScreenButton.clicked.connect( self.videoWidget.setFullScreen) self.videoWidget.fullScreenChanged.connect( self.fullScreenButton.setChecked) if self.fullScreenButton.isChecked(): self.videoWidget.setFullScreen(True) else: self.fullScreenButton.clicked.disconnect( self.videoWidget.setFullScreen) self.videoWidget.fullScreenChanged.disconnect( self.fullScreenButton.setChecked) self.videoWidget.setFullScreen(False) self.colorButton.setEnabled(available) def setTrackInfo(self, info): self.trackInfo = info if self.statusInfo != "": self.setWindowTitle("%s | %s" % (self.trackInfo, self.statusInfo)) else: self.setWindowTitle(self.trackInfo) def setStatusInfo(self, info): self.statusInfo = info if self.statusInfo != "": self.setWindowTitle("%s | %s" % (self.trackInfo, self.statusInfo)) else: self.setWindowTitle(self.trackInfo) def displayErrorMessage(self): self.setStatusInfo(self.player.errorString()) def updateDurationInfo(self, currentInfo): duration = self.duration if currentInfo or duration: currentTime = QTime((currentInfo / 3600) % 60, (currentInfo / 60) % 60, currentInfo % 60, (currentInfo * 1000) % 1000) totalTime = QTime((duration / 3600) % 60, (duration / 60) % 60, duration % 60, (duration * 1000) % 1000) format = 'hh:mm:ss' if duration > 3600 else 'mm:ss' tStr = currentTime.toString(format) + " / " + totalTime.toString( format) else: tStr = "" self.labelDuration.setText(tStr) def showColorDialog(self): if self.colorDialog is None: brightnessSlider = QSlider(Qt.Horizontal) brightnessSlider.setRange(-100, 100) brightnessSlider.setValue(self.videoWidget.brightness()) brightnessSlider.sliderMoved.connect( self.videoWidget.setBrightness) self.videoWidget.brightnessChanged.connect( brightnessSlider.setValue) contrastSlider = QSlider(Qt.Horizontal) contrastSlider.setRange(-100, 100) contrastSlider.setValue(self.videoWidget.contrast()) contrastSlider.sliderMoved.connect(self.videoWidget.setContrast) self.videoWidget.contrastChanged.connect(contrastSlider.setValue) hueSlider = QSlider(Qt.Horizontal) hueSlider.setRange(-100, 100) hueSlider.setValue(self.videoWidget.hue()) hueSlider.sliderMoved.connect(self.videoWidget.setHue) self.videoWidget.hueChanged.connect(hueSlider.setValue) saturationSlider = QSlider(Qt.Horizontal) saturationSlider.setRange(-100, 100) saturationSlider.setValue(self.videoWidget.saturation()) saturationSlider.sliderMoved.connect( self.videoWidget.setSaturation) self.videoWidget.saturationChanged.connect( saturationSlider.setValue) layout = QFormLayout() layout.addRow("亮度", brightnessSlider) layout.addRow("对比度", contrastSlider) layout.addRow("色调", hueSlider) layout.addRow("饱和度", saturationSlider) button = QPushButton("关闭") layout.addRow(button) self.colorDialog = QDialog(self) self.colorDialog.setWindowTitle("颜色选项") self.colorDialog.setLayout(layout) button.clicked.connect(self.colorDialog.close) self.colorDialog.show()
class VideoPlayer(QWidget): def __init__(self, aPath, parent=None): super(VideoPlayer, self).__init__(parent) self.setAttribute(Qt.WA_NoSystemBackground, True) self.setAcceptDrops(True) self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.StreamPlayback) self.mediaPlayer.setVolume(80) self.videoWidget = QVideoWidget(self) self.videoWidget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.videoWidget.setMinimumSize(QSize(640, 360)) self.lbl = QLineEdit('00:00:00') self.lbl.setReadOnly(True) self.lbl.setFixedWidth(70) self.lbl.setUpdatesEnabled(True) self.lbl.setStyleSheet(stylesheet(self)) self.elbl = QLineEdit('00:00:00') self.elbl.setReadOnly(True) self.elbl.setFixedWidth(70) self.elbl.setUpdatesEnabled(True) self.elbl.setStyleSheet(stylesheet(self)) self.playButton = QPushButton() self.playButton.setEnabled(False) self.playButton.setFixedWidth(32) self.playButton.setStyleSheet("background-color: black") self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay)) self.playButton.clicked.connect(self.play) self.positionSlider = QSlider(Qt.Horizontal, self) self.positionSlider.setStyleSheet(stylesheet(self)) self.positionSlider.setRange(0, 100) self.positionSlider.sliderMoved.connect(self.setPosition) self.positionSlider.sliderMoved.connect(self.handleLabel) self.positionSlider.setSingleStep(2) self.positionSlider.setPageStep(20) self.positionSlider.setAttribute(Qt.WA_TranslucentBackground, True) self.clip = QApplication.clipboard() self.process = QProcess(self) self.process.readyRead.connect(self.dataReady) self.process.finished.connect(self.playFromURL) self.myurl = "" # channel list self.channelList = QListView(self) self.channelList.setMinimumSize(QSize(150, 0)) self.channelList.setMaximumSize(QSize(150, 4000)) self.channelList.setFrameShape(QFrame.Box) self.channelList.setObjectName("channelList") self.channelList.setStyleSheet("background-color: black; color: #585858;") self.channelList.setFocus() # for adding items to list must create a model self.model = QStandardItemModel() self.channelList.setModel(self.model) self.controlLayout = QHBoxLayout() self.controlLayout.setContentsMargins(5, 0, 5, 0) self.controlLayout.addWidget(self.playButton) self.controlLayout.addWidget(self.lbl) self.controlLayout.addWidget(self.positionSlider) self.controlLayout.addWidget(self.elbl) self.mainLayout = QHBoxLayout() # contains video and cotrol widgets to the left side self.layout = QVBoxLayout() self.layout.setContentsMargins(0, 0, 0, 0) self.layout.addWidget(self.videoWidget) self.layout.addLayout(self.controlLayout) # adds channels list to the right self.mainLayout.addLayout(self.layout) self.mainLayout.addWidget(self.channelList) self.setLayout(self.mainLayout) self.myinfo = "©2020\nTIVOpy v1.0" self.widescreen = True #### shortcuts #### self.shortcut = QShortcut(QKeySequence("q"), self) self.shortcut.activated.connect(self.handleQuit) self.shortcut = QShortcut(QKeySequence("u"), self) self.shortcut.activated.connect(self.playFromURL) self.shortcut = QShortcut(QKeySequence(Qt.Key_Space), self) self.shortcut.activated.connect(self.play) self.shortcut = QShortcut(QKeySequence(Qt.Key_F), self) self.shortcut.activated.connect(self.handleFullscreen) self.shortcut = QShortcut(QKeySequence(Qt.Key_Escape), self) self.shortcut.activated.connect(self.exitFullscreen) self.shortcut.activated.connect(self.handleFullscreen) self.shortcut = QShortcut(QKeySequence("i"), self) self.shortcut.activated.connect(self.handleInfo) self.shortcut = QShortcut(QKeySequence("s"), self) self.shortcut.activated.connect(self.toggleSlider) self.shortcut = QShortcut(QKeySequence(Qt.Key_Right), self) self.shortcut.activated.connect(self.forwardSlider) self.shortcut = QShortcut(QKeySequence(Qt.Key_Left), self) self.shortcut.activated.connect(self.backSlider) self.mediaPlayer.setVideoOutput(self.videoWidget) self.mediaPlayer.stateChanged.connect(self.mediaStateChanged) self.mediaPlayer.positionChanged.connect(self.positionChanged) self.mediaPlayer.positionChanged.connect(self.handleLabel) self.mediaPlayer.durationChanged.connect(self.durationChanged) self.mediaPlayer.error.connect(self.handleError) self.populateChannelList() self.selectChannel() self.initialPlay() def playFromURL(self): self.mediaPlayer.pause() self.myurl = self.clip.text() self.mediaPlayer.setMedia(QMediaContent(QUrl(self.myurl))) self.playButton.setEnabled(True) self.mediaPlayer.play() self.hideSlider() print(self.myurl) def dataReady(self): self.myurl = str(self.process.readAll(), encoding='utf8').rstrip() ### self.myurl = self.myurl.partition("\n")[0] print(self.myurl) self.clip.setText(self.myurl) self.playFromURL() def play(self): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.mediaPlayer.pause() else: self.mediaPlayer.play() def mediaStateChanged(self, state): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.playButton.setIcon( self.style().standardIcon(QStyle.SP_MediaPause)) else: self.playButton.setIcon( self.style().standardIcon(QStyle.SP_MediaPlay)) def positionChanged(self, position): self.positionSlider.setValue(position) def durationChanged(self, duration): self.positionSlider.setRange(0, duration) mtime = QTime(0, 0, 0, 0) mtime = mtime.addMSecs(self.mediaPlayer.duration()) self.elbl.setText(mtime.toString()) def setPosition(self, position): self.mediaPlayer.setPosition(position) def handleError(self): self.playButton.setEnabled(False) print("Error: ", self.mediaPlayer.errorString()) def handleQuit(self): self.mediaPlayer.stop() print("Goodbye ...") app.quit() def contextMenuRequested(self, point): menu = QMenu() actionURL = menu.addAction(QIcon.fromTheme("browser"), "URL from Clipboard (u)") menu.addSeparator() actionToggle = menu.addAction(QIcon.fromTheme("next"), "Show / Hide Channels (s)") actionFull = menu.addAction(QIcon.fromTheme("view-fullscreen"), "Fullscreen (f)") menu.addSeparator() actionInfo = menu.addAction(QIcon.fromTheme("help-about"), "About (i)") menu.addSeparator() actionQuit = menu.addAction(QIcon.fromTheme("application-exit"), "Exit (q)") actionQuit.triggered.connect(self.handleQuit) actionFull.triggered.connect(self.handleFullscreen) actionInfo.triggered.connect(self.handleInfo) actionToggle.triggered.connect(self.toggleSlider) actionURL.triggered.connect(self.playFromURL) menu.exec_(self.mapToGlobal(point)) def wheelEvent(self, event): mscale = event.angleDelta().y() / 13 self.mediaPlayer.setVolume(self.mediaPlayer.volume() + mscale) print("Volume: " + str(self.mediaPlayer.volume())) def mouseDoubleClickEvent(self, event): if event.buttons() == Qt.LeftButton: self.handleFullscreen() def handleFullscreen(self): if self.windowState() and Qt.WindowFullScreen: self.showNormal() else: self.showFullScreen() def exitFullscreen(self): self.showNormal() def handleInfo(self): QMessageBox.about(self, "About", self.myinfo) def toggleSlider(self): if self.positionSlider.isVisible(): self.hideSlider() else: self.showSlider() def hideSlider(self): self.channelList.hide() self.playButton.hide() self.lbl.hide() self.positionSlider.hide() self.elbl.hide() def showSlider(self): self.channelList.show() self.playButton.show() self.lbl.show() self.positionSlider.show() self.elbl.show() self.channelList.setFocus() def forwardSlider(self): self.mediaPlayer.setPosition(self.mediaPlayer.position() + 1000 * 60) def backSlider(self): self.mediaPlayer.setPosition(self.mediaPlayer.position() - 1000 * 60) def volumeUp(self): self.mediaPlayer.setVolume(self.mediaPlayer.volume() + 10) print("Volume: " + str(self.mediaPlayer.volume())) def volumeDown(self): self.mediaPlayer.setVolume(self.mediaPlayer.volume() - 10) print("Volume: " + str(self.mediaPlayer.volume())) def dragEnterEvent(self, event): if event.mimeData().hasUrls(): event.accept() elif event.mimeData().hasText(): event.accept() else: event.ignore() def dropEvent(self, event): print("drop") if event.mimeData().hasUrls(): url = event.mimeData().urls()[0].toString() print("url = ", url) self.mediaPlayer.stop() self.mediaPlayer.setMedia(QMediaContent(QUrl(url))) self.playButton.setEnabled(True) self.mediaPlayer.play() elif event.mimeData().hasText(): mydrop = event.mimeData().text() print("generic url = ", mydrop) self.mediaPlayer.setMedia(QMediaContent(QUrl(mydrop))) self.playButton.setEnabled(True) self.mediaPlayer.play() self.hideSlider() def loadFilm(self, f): self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile(f))) self.playButton.setEnabled(True) self.mediaPlayer.play() def populateChannelList(self): # file must be in same directory as the script FILEPATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), "canaletv.txt") # lines from file with "channel name" -- "link" channelArray = [] # split file by line and adding it to the array with open(FILEPATH) as f: for line in f: channelArray.append(line.rstrip()) # dictionary with key = channel name and value = link self.channelDict = dict(ch.split(" -- ") for ch in channelArray) for channel in self.channelDict.keys(): item = QStandardItem(channel) self.model.appendRow(item) def selectedItemBehavior(self, index): # gets the link for the selected channel and plays it itms = self.channelList.selectedIndexes() for it in itms: channel = it.data() link = self.channelDict[channel] self.mediaPlayer.setMedia(QMediaContent(QUrl(link))) self.play() def selectChannel(self): # selecting channel from sidebar calls selectedItemBehavior self.selModel = self.channelList.selectionModel() self.selModel.selectionChanged.connect(self.selectedItemBehavior) def initialPlay(self): # play somenting when app opens self.mediaPlayer.setMedia(QMediaContent(QUrl("https://vid.hls.protv.ro/proxhdn/proxhd_3_34/index.m3u8?1"))) self.play() def handleLabel(self): self.lbl.clear() mtime = QTime(0, 0, 0, 0) self.time = mtime.addMSecs(self.mediaPlayer.position()) self.lbl.setText(self.time.toString())
class VideoPlayer(QWidget): def __init__(self, parent=None): super(VideoPlayer, self).__init__(parent) self._source = None self._total_duration = 0 self.widget_layout = QVBoxLayout() self.media_player = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.video_player = QVideoWidget() self.widget_layout.addWidget(self.video_player) self.media_player.setVideoOutput(self.video_player) # self.media_player.stateChanged.connect(self.mediaStateChanged) self.media_player.positionChanged.connect(self.on_positionChanged) self.signals = VideoPlayerWidgetSignals() self.media_player.durationChanged.connect(self.on_durationChanged) self.setLayout(self.widget_layout) print(self.media_player.duration()) @property def total_duration(self): return self._total_duration @total_duration.setter def total_duration(self, val): self._total_duration = val @property def source(self): return self._source @source.setter def source(self, value): self._source = value self._total_duration = math.floor(VideoUtilities.duration(self.source)) def play(self): if self._source: self.media_player.setMedia( QMediaContent(QUrl.fromLocalFile(self._source))) self.media_player.play() def resume(self): if self.media_player.state() == QMediaPlayer.PlayingState: self.media_player.pause() else: self.media_player.play() def stop(self): if self.media_player.state() == QMediaPlayer.PlayingState: self.media_player.stop() def go_to(self, second: int): if self.media_player: self.media_player.setPosition(second * 1000) @QtCore.pyqtSlot('qint64') def on_positionChanged(self, position): self.signals.video_position_changed_signal.emit( math.floor(position / 1000), self.total_duration) if self.media_player.state() == QMediaPlayer.StoppedState: if 0 <= position <= self.total_duration * 1000: self.media_player.play() @QtCore.pyqtSlot('qint64') def on_durationChanged(self, duration): self.signals.video_duration_changed_signal.emit( math.floor(duration / 1000))
class 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 videoViewer(QDialog): def __init__(self): super(videoViewer,self).__init__() loadUi('..\gui\viewer.ui',self) self.setWindowTitle('Recorded Videos') self.setWindowIcon(QIcon('..\resources\icon.png')) self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface) videoWidget = QVideoWidget(self) layout = QVBoxLayout() layout.addWidget(videoWidget) self.mediaPlayer.setVideoOutput(videoWidget) self.videoWidget.setLayout(layout) self.userPath = os.path.join(os.getcwd(),'..\data') userList = [o for o in os.listdir(self.userPath) if os.path.isdir(os.path.join(self.userPath,o))] self.list1.addItems(userList) self.list1.itemClicked.connect(self.loadFile) self.playButton.clicked.connect(self.play) self.pauseButton.clicked.connect(self.pause) self.stopButton.clicked.connect(self.stop) self.exitButton.clicked.connect(self.exit) self.playButton.setEnabled(False) self.pauseButton.setEnabled(False) self.stopButton.setEnabled(False) self.timer = QTimer(self) self.timer.timeout.connect(self.updateFrame) self.understanding1.setText('-') self.understanding2.setText('-') self.data = pickle.load(open('..\data\data.pkl','rb')) self.mediaPlayer.mediaStatusChanged.connect(self.mediaStatusfn) def mediaStatusfn(self): if self.mediaPlayer.position()==self.mediaPlayer.duration(): self.mediaPlayer.stop() def updateFrame(self): currentFrame = round(self.mediaPlayer.position()*30/1000) totalFrame = round(self.mediaPlayer.duration()*30/1000) if currentFrame>totalFrame: self.timer.stop() self.mediaPlayer.stop() else: if self.understandingData[self.i][0]<currentFrame and self.i<len(self.understandingData)-1: self.i += 1 self.understanding1.setText(str(self.understandingData[self.i][1])) self.understanding2.setText(str(self.understandingData[self.i][1])) def play(self): self.mediaPlayer.play() self.pauseButton.setEnabled(True) self.playButton.setEnabled(False) self.stopButton.setEnabled(True) self.timer.start(30) def pause(self): self.mediaPlayer.pause() self.playButton.setEnabled(True) self.pauseButton.setEnabled(False) self.timer.stop() def stop(self): self.mediaPlayer.stop() self.playButton.setEnabled(True) self.pauseButton.setEnabled(False) self.stopButton.setEnabled(False) self.timer.stop() def exit(self): self.close() def loadFile(self, item): self.filePath = os.path.join(self.userPath,item.text()) fileList = [o for o in os.listdir(self.filePath) if not os.path.isdir(os.path.join(self.filePath,o))] self.list2.clear() self.list2.addItems(fileList) self.list2.itemClicked.connect(self.playFile) def playFile(self, item): if (os.path.splitext(item.text())[-1].lower()=='.avi'): self.fileLabel.setText(item.text()) self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile(os.path.join(self.filePath,item.text())))) for file, understanding in self.data.items(): if os.path.basename(file)==item.text(): self.understandingData = understanding break self.playButton.setEnabled(True) self.pauseButton.setEnabled(False) self.stopButton.setEnabled(False) self.i = 0
class jaabaGUI(QMainWindow): """ controller for the blob labeling GUI""" def __init__(self,parent=None): QMainWindow.__init__(self,parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) #add new slider # self.positionSlider=QSlider(Qt.Horizontal) # self.positionSlider.setGeometry (800,800,100,30) # self.positionSlider.setRange(0, 0) # self.positionSlider.sliderMoved.connect(self.setPosition) #setup Video #video player self.mediaPlayer1 = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.mediaPlayer2 = QMediaPlayer(None, QMediaPlayer.VideoSurface) #self.mediaPlayer.metaDataChanged.connect(self.metaDataChanged) self.mediaPlayer1.durationChanged.connect(self.durationChanged) self.mediaPlayer1.positionChanged.connect(self.positionChanged) self.mediaPlayer2.positionChanged.connect(self.positionChanged) #visualizetion self.scene = QGraphicsScene() self.ui.graphicsView.setScene(self.scene) #self.scene.setBackgroundBrush(Qt.black) self.videoItem1 = QGraphicsVideoItem() self.videoItem2 = QGraphicsVideoItem() self.scene.addItem(self.videoItem1) self.scene.addItem(self.videoItem2) self.mediaPlayer1.setVideoOutput(self.videoItem1) self.mediaPlayer2.setVideoOutput(self.videoItem2) #slide bar print self.ui.horizontalSlider self.ui.horizontalSlider.setRange(0, 0) self.ui.horizontalSlider.sliderMoved.connect(self.setPosition) # self.ui.horizontalSlider.sliderPressed.connect(self.sliderPressed) #print self.ui.graphicsView.width()/2,self.ui.graphicsView.height() #self.videoItem1.setSize(QSizeF(self.ui.graphicsView.width()/2,self.ui.graphicsView.height())) #self.videoItem2.setSize(QSizeF(self.ui.graphicsView.width()*10,self.ui.graphicsView.height()*10)) # self.videoItem2.setSize(graphicsView.size()) #self.videoItem2.setOffset(QPointF(500,500)) #self.videoItem2.setOffset(QPointF(self.ui.graphicsView.width()/2,0)) #self.videoItem2.setPos(QPointF(0,0)) # print self.ui.graphicsView.width(), self.ui.graphicsView.height() # print self.ui.graphicsView.size() # print self.videoItem2.boundingRect().width(), self.videoItem2.boundingRect().height() # print self.ui.graphicsView.sceneRect() #self.mediaPlayer.stateChanged.connect(self.mediaStateChanged) #callbacks self.ui.actionQuit.triggered.connect(self.quit) self.ui.actionLoad_Project.triggered.connect(self.loadVideo) #self.ui.buttonPlay.clicked[bool].connect(self.setToggleText) self.ui.buttonPlay.clicked.connect(self.play) #print self.ui.graphicsView.sizeHint() #initialization self.loaded = False self.videoFilename = None self.frame_count=None self.width=None self.height=None self.frame_trans=None # ###actions starts from here### def quit(self): QApplication.quit() def loadVideo(self): self.writeLog("Loading video...") self.videoFilename = QFileDialog.getOpenFileName(self, 'Open File', '.')[0] if not self.videoFilename: self.writeLog("User cancelled - no video loaded") return else: cap=cv2.VideoCapture(self.videoFilename) self.frame_count=cap.get(cv2.CAP_PROP_FRAME_COUNT) self.width=cap.get(3) self.height=cap.get(4) self.mediaPlayer2.setMedia(QMediaContent(QUrl.fromLocalFile(self.videoFilename ))) self.mediaPlayer1.setMedia(QMediaContent(QUrl.fromLocalFile(self.videoFilename ))) self.ui.buttonPlay.setEnabled(True) # self.mediaPlayer2.setVideoOutput(self.videoItem2) # self.mediaPlayer1.setVideoOutput(self.videoItem1) # size= self.videoItem2.nativeSize() # print size #print self.mediaPlayer.duration() #print self.mediaPlayer.metaData() self.writeLog("Video loaded!") def play(self): self.videoItem1.setAspectRatioMode(0) self.videoItem2.setAspectRatioMode(0) self.scene.setSceneRect(0,0,self.ui.graphicsView.width(),self.ui.graphicsView.height()) self.videoItem1.setSize(QSizeF(self.ui.graphicsView.width()/2,self.ui.graphicsView.height())) self.videoItem2.setSize(QSizeF(self.ui.graphicsView.width()/2,self.ui.graphicsView.height())) self.videoItem1.setPos(QPointF(0,0)) self.videoItem2.setPos(QPointF(self.ui.graphicsView.width()/2,0)) #self.ui.graphicsView.setGeometry(0,0, 600,800) #print 'graphicsView size', self.ui.graphicsView.size() #print 'graphicsScene size', self.scene.sceneRect() #self.videoItem2.setSize(QSizeF(1000,300)) #print 'graphicsVideoItem size',self.videoItem2.size() # print 'item x',self.videoItem2.scenePos().x() # print 'item y', self.videoItem2.scenePos().y() # print 'item x',self.videoItem1.scenePos().x() # print 'item y', self.videoItem1.scenePos().y() if self.mediaPlayer1.state() == QMediaPlayer.PlayingState: self.ui.buttonPlay.setIcon(self.ui.style().standardIcon(PyQt5.QtWidgets.QStyle.SP_MediaPlay)) self.ui.buttonPlay.setText("Play") self.mediaPlayer1.pause() self.writeLog("Video paused") else: self.ui.buttonPlay.setIcon(self.ui.style().standardIcon(PyQt5.QtWidgets.QStyle.SP_MediaPause)) self.ui.buttonPlay.setText("Stop") self.mediaPlayer1.play() self.writeLog("Playing video") if self.mediaPlayer2.state() == QMediaPlayer.PlayingState: self.mediaPlayer2.pause() else: self.mediaPlayer2.play() #size= self.videoItem2.nativeSize() # print self.mediaPlayer.duration() #print self.mediaPlayer.metaData() # print self.ui.graphicsView.width(), self.ui.graphicsView.height() # print self.ui.graphicsView.size() # print self.videoItem2.boundingRect().width(), self.videoItem2.boundingRect().height() # print self.ui.graphicsView.sceneRect() # print self.scene.sceneRect() # print self.ui.graphicsView.sizeHint() def setPosition(self, position): self.mediaPlayer1.setPosition(position) self.mediaPlayer2.setPosition(position) # when position of media changed, set slider and text box accordingly. def positionChanged(self, position): self.ui.horizontalSlider.setValue(position) if isinstance(self.frame_trans,float): # print type(position),position # print type(self.frame_trans),self.frame_trans # print position/self.frame_trans self.ui.lineEdit.setText(str(int(round(position/self.frame_trans,0)))) self.writeLog(str(position)) def durationChanged(self, duration): self.ui.horizontalSlider.setRange(0, duration) self.frame_trans=self.mediaPlayer1.duration()/self.frame_count print self.frame_trans def writeLog(self,text): self.ui.log.setText(text)
class NewProject(QtWidgets.QWidget, Ui_NewProject): def __init__(self,projectfile,MainWidget): QtWidgets.QWidget.__init__(self) self.setupUi(self) self.setWindowFlags(Qt.WindowStaysOnTopHint) self.Main = MainWidget self.iface = self.Main.iface self.muteButton.setIcon( self.style().standardIcon(QStyle.SP_MediaVolume)) self.replayPlay_pushButton.setIcon( self.style().standardIcon(QStyle.SP_MediaPlay)) if projectfile.split('.')[-1] =="vgp": self.projectfile = projectfile else: self.projectfile = projectfile +'.vgp' self.videofile = None self.GPXfile = None self.GPXList = None self.fps = None self.RealFps = None self.DB = None self.player = QMediaPlayer() self.player.setVideoOutput(self.video_frame_2) self.player.durationChanged.connect(self.durationChanged) self.player.positionChanged.connect(self.positionChanged) self.player.stateChanged.connect(self.mediaStateChanged) self.toolButton_3.clicked.connect(self.ManageDB) self.pushButton_2.clicked.connect(self.Synchronize) self.pushButton.clicked.connect(self.SelectVideoGPX) self.replayPlay_pushButton.clicked.connect(self.PlayPause) self.muteButton.clicked.connect(self.MuteUnmute) self.horizontalSlider.sliderMoved.connect(self.setPosition) self.toolButton.clicked.connect(self.SkipBackward) self.toolButton_2.clicked.connect(self.SkipForward) self.SkipBacktoolButton_7.clicked.connect(self.BackwardFrame) self.SkipFortoolButton_8.clicked.connect(self.ForwardFrame) def closeEvent(self, *args, **kwargs): self.player.stop() return QtWidgets.QWidget.closeEvent(self, *args, **kwargs) def mediaStateChanged(self, state): if self.player.state() == QMediaPlayer.PlayingState: self.replayPlay_pushButton.setIcon( self.style().standardIcon(QStyle.SP_MediaPause)) else: self.replayPlay_pushButton.setIcon( self.style().standardIcon(QStyle.SP_MediaPlay)) def Synchronize(self): TimeItem = self.comboBox.currentIndex() duration = self.player.duration() position = self.player.position() VideoPartLen = round((duration-position) / 1000) GpxPartition = self.GPXList[TimeItem:VideoPartLen+TimeItem] outputFile = open(self.projectfile ,'w') if self.DB == None: outputFile.write('VideoGis Project v0.1 DO NOT MODIFY'+ '\nVideo file location = ' +self.videofile+ '\nVideo start at msecond: '+ str(self.player.position())+ ' #fps = '+str(self.RealFps)+ '\nDB = None'+ '\n'+'Latitude # Longitude # Ele # Speed (m/s) # Course # Time \n') else: outputFile.write('Video file location = ' +self.videofile+ '\nVideo start at msecond: '+ str(self.player.position())+ ' #fps = '+str(self.RealFps)+ '\nDB = '+str(self.DB.dataProvider().dataSourceUri().split('|')[0])+ '\n'+'Latitude # Longitude # Ele # Speed (m/s) # Course # Time \n') Counter = 0 for x in GpxPartition: if Counter != 0: ActualLatitude = x[1][0] ActualLongitude = x[1][1] PreviousLatitude = GpxPartition[Counter-1][1][0] PreviousLongitude = GpxPartition[Counter-1][1][1] GeodesicCalcolus = Geodesic.WGS84.Inverse(PreviousLatitude, PreviousLongitude, ActualLatitude, ActualLongitude) Speed = GeodesicCalcolus['s12'] /1 Course = GeodesicCalcolus['azi2'] if Course < 0: Course += 360 Ele = x[1][2] Time = x[1][3] Counter = Counter + 1 else: ActualLatitude = x[1][0] ActualLongitude = x[1][1] PreviousLatitude = GpxPartition[Counter+1][1][0] PreviousLongitude = GpxPartition[Counter+1][1][1] GeodesicCalcolus = Geodesic.WGS84.Inverse(ActualLatitude, ActualLongitude, PreviousLatitude, PreviousLongitude) Speed = GeodesicCalcolus['s12'] * 1 Course = GeodesicCalcolus['azi2'] if Course < 0: Course += 360 Ele = x[1][2] Time = x[1][3] Counter = Counter + 1 outputFile.write(str(ActualLatitude)+' '+str(ActualLongitude)+' '+str(Ele)+' '+str(Speed)+' '+str(Course)+' '+str(Time)+'\n') outputFile.close() self.Main.LoadProjFromNew(self.projectfile) if os.name == 'nt': os.remove (self.tmp) self.close() def SelectVideoGPX(self): if os.name == 'nt': ffmpeg = os.path.dirname(__file__)+'/FFMPEG/ffmpeg.exe' versione = 'ffmpeg.exe' else: ffmpeg = os.path.dirname(__file__)+'/FFMPEG/./ffmpeg' versione = 'ffmpeg' if os.path.exists(ffmpeg) == True: self.comboBox.clear() if self.player.state() == QMediaPlayer.PlayingState: self.player.pause() self.videofile = None self.GPXfile = None options = QFileDialog.Options() options |= QFileDialog.DontUseNativeDialog self.videofile, _ = QFileDialog.getOpenFileName(self,"Select Video File", "","All Files (*);;Video File (*.mp4 *.avi *.ogv)", options=options) if self.videofile: self.GPXfile, _ = QFileDialog.getOpenFileName(self,"Select GPX file", "","All Files (*);;Video File (*.gpx)", options=options) if self.GPXfile: self.ParseGpx(self.GPXfile) self.LoadVideo(self.videofile) self.replayPosition_label.setText( "-:- / -:-") else: ret = QMessageBox.warning(self, "Warning", 'missing ffmpeg binaries, please download it from https://github.com/sagost/VideoUavTracker/blob/master/FFMPEG/'+versione+' and paste it in /.qgis3/python/plugins/Video_UAV_Tracker/FFMPEG/ ', QMessageBox.Ok) self.close() def ParseGpx(self,GPXfile): gpx = parse(GPXfile) track = gpx.getElementsByTagName("trkpt") GPXList = [] Error = 0 GpxProgressiveNumber = 0 Timestamp = 'Segnaposto' for name in track: dict = {'Lat': 0, 'Lon': 0, 'Ele': 0, 'Time':0} a = (name.toprettyxml(indent = '') ).split() for x in a: if x.find('lat') == 0: lat = float(x.split('"')[1]) dict['Lat'] = float(x.split('"')[1]) elif x.find('lon') == 0: lon = float(x.split('"')[1]) dict['Lon'] = float(x.split('"')[1]) elif x.find('<ele>') == 0: dict['Ele'] = float(x[5:-6]) elif x.find('<time>') == 0: try: gpxtime = time.strftime('%Y-%m-%dT%H:%M:%S.%fZ',time.strptime(x[6:-7], '%Y-%m-%dT%H:%M:%S.%fZ')) dict['Time']= x[6:-7] except ValueError: try: gpxtime = time.strftime('%Y-%m-%dT%H:%M:%SZ',time.strptime(x[6:-7],'%Y-%m-%dT%H:%M:%SZ')) dict['Time']= x[6:-7] except ValueError: try: gpxtime = time.strftime('%Y-%m-%dT%H:%M:%S',time.strptime(x[6:-7],'%Y-%m-%dT%H:%M:%S')) dict['Time']= x[6:-7] except ValueError: try: gpxtime = time.strftime('%Y-%m-%dT%H.%M.%S',time.strptime(x[6:-7],'%Y-%m-%dT%H.%M.%S')) dict['Time']= x[6:-7] except ValueError: try: gpxtime = time.strftime('%Y-%m-%dT%H.%M.%S',time.strptime(x[6:-13],'%Y-%m-%dT%H.%M.%S')) dict['Time']= x[6:-13] except ValueError: try: gpxtime = time.strftime('%Y-%m-%dT%H.%M.%S',time.strptime(x[6:-13],'%Y-%m-%dT%H:%M:%S')) dict['Time']= x[6:-13] except ValueError: Error = 1 FormatoErrore = str(x) if dict['Time'] != Timestamp: Point = [dict['Lat'],dict['Lon'],dict['Ele'],dict['Time']] self.comboBox.addItem(str(GpxProgressiveNumber) + '-'+gpxtime ) GPXList.append([GpxProgressiveNumber,Point]) GpxProgressiveNumber = GpxProgressiveNumber + 1 Timestamp = dict['Time'] else: Timestamp = dict['Time'] if Error == 0: self.GPXList = GPXList else: ret = QMessageBox.warning(self, "Warning", FormatoErrore +' UNKOWN GPX TIME FORMAT - ABORTED', QMessageBox.Ok) self.close def LoadVideo(self,videofile): fps = self.getVideoDetails(str(videofile)) self.RealFps = float(fps) self.fps = (1 / self.RealFps )*1000 url = QUrl.fromLocalFile(str(self.videofile)) mc = QMediaContent(url) self.player.setMedia(mc) self.player.play() def setPosition(self, position): self.player.setPosition(position*1000) def durationChanged(self, duration): duration /= 1000 self.horizontalSlider.setMaximum(duration) def secTotime(self,seconds): m, s = divmod(seconds, 60) h, m = divmod(m, 60) return "%d:%02d:%02d" % (h, m, s) def positionChanged(self, progress): duration = self.player.duration() totalTime = self.secTotime(duration/1000) actualTime = self.secTotime(progress/1000) self.replayPosition_label.setText(actualTime + ' / '+totalTime) progress /= 1000 if not self.horizontalSlider.isSliderDown(): self.horizontalSlider.setValue(progress) def MuteUnmute(self): if self.player.mediaStatus() == 6 : if self.player.isMuted() == 1: self.player.setMuted(0) self.muteButton.setIcon( self.style().standardIcon(QStyle.SP_MediaVolume)) elif self.player.isMuted() == 0: self.player.setMuted(1) self.muteButton.setIcon( self.style().standardIcon(QStyle.SP_MediaVolumeMuted)) def PlayPause(self): if self.player.state() == QMediaPlayer.PlayingState: self.player.pause() else: self.player.play() def getVideoDetails(self,filepath): if os.name == 'nt': tmp = os.path.dirname(__file__)[0:-18]+'/Video_UAV_Tracker/tmp' tmp2 = '"'+tmp+'"' filepath2 = '"'+filepath+'"' a = open(tmp,'w') a.close() ffmpeg = '"'+os.path.dirname(__file__)[0:-18]+'/Video_UAV_Tracker/FFMPEG/ffmpeg.exe'+'"' a = os.popen(str(ffmpeg + ' -i '+filepath2+' 2> '+tmp2)) while os.stat(tmp).st_size < 1500: pass a = open(tmp,'r') lines = a.readlines() a.close() for l in lines: l = l.strip() if str(l).startswith("Stream #0:0"): linea = str(l).split(',')[-4] dopo = linea.find('fps') fps = float(linea[0:dopo]) self.tmp = tmp return fps else: tmpf = tempfile.NamedTemporaryFile() ffmpeg = os.path.dirname(__file__)+'/FFMPEG/./ffmpeg' os.system(str(ffmpeg)+" -i \"%s\" 2> %s" % (filepath, tmpf.name)) lines = tmpf.readlines() tmpf.close() for l in lines: l = l.strip() if str(l).startswith("b'Stream #0:0"): linea = str(l).split(',')[-4] dopo = linea.find('fps') fps = float(linea[0:dopo]) return fps def SkipForward(self): position = self.player.position() self.player.setPosition(position+1000) def SkipBackward(self): position = self.player.position() self.player.setPosition(position-1000) def ForwardFrame(self): position = self.player.position() self.player.setPosition(position+int(self.fps)) def BackwardFrame(self): position = self.player.position() self.player.setPosition(position-int(self.fps)) def ManageDB(self): self.player.pause() shapeFileFirst,_ = QFileDialog.getSaveFileName(caption = 'Save shape file', filter = "Esri shp (*.shp)") if shapeFileFirst: if shapeFileFirst.split('.')[-1] == 'shp': shapeFile = shapeFileFirst else: shapeFile = shapeFileFirst + '.shp' try: os.remove(shapeFile) os.remove(shapeFileFirst.split('.')[0]+'.qpg') os.remove(shapeFileFirst.split('.')[0]+'.prj') os.remove(shapeFileFirst.split('.')[0]+'.cpg') os.remove(shapeFileFirst.split('.')[0]+'.shx') os.remove(shapeFileFirst.split('.')[0]+'.dbf') except OSError: pass crs = QgsCoordinateReferenceSystem(4326, QgsCoordinateReferenceSystem.EpsgCrsId) fields = QgsFields() QgsVectorFileWriter(shapeFile, "CP1250", fields, QgsWkbTypes.Point, crs, "ESRI Shapefile") EmptyLayer = QgsVectorLayer(shapeFile, shapeFile.split('.')[0].split('/')[-1], 'ogr') self.dialoga = TableManager(self.iface, EmptyLayer,self) self.dialoga.exec_() def AcceptNewDB(self,DB): self.DB = DB
class MainUi(QtWidgets.QMainWindow): def __init__(self): super().__init__() self.init_ui() self.player = QMediaPlayer(self) def init_ui(self): self.setFixedSize(550, 325) self.main_widget = QtWidgets.QWidget() # 创建窗口主部件 self.main_layout = QtWidgets.QGridLayout() # 创建主部件的网格布局 self.main_widget.setLayout(self.main_layout) # 设置窗口主部件布局为网格布局 self.left_widget = QtWidgets.QWidget() # 创建左侧部件 self.left_widget.setObjectName('left_widget') self.left_layout = QtWidgets.QGridLayout() # 创建左侧部件的网格布局层 self.left_widget.setLayout(self.left_layout) # 设置左侧部件布局为网格 self.left_widget.setStyleSheet(''' QPushButton{border:none;color:white;} QPushButton#left_label{ border:none; border-bottom:1px solid white; font-size:18px; font-weight:700; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; } QPushButton#left_button:hover{border-left:4px solid red;font-weight:700;} ''') self.right_widget = QtWidgets.QWidget() # 创建右侧部件 self.right_widget.setObjectName('right_widget') self.right_layout = QtWidgets.QGridLayout() self.right_widget.setLayout(self.right_layout) # 设置右侧部件布局为网格 self.right_bar_widget = QtWidgets.QWidget() # 右侧顶部搜索框部件 self.right_bar_layout = QtWidgets.QGridLayout() # 右侧顶部搜索框网格布局 self.right_bar_widget.setLayout(self.right_bar_layout) self.search_icon = QtWidgets.QLabel(chr(0xf002) + ' ' + '搜索 ') self.search_icon.setFont(qtawesome.font('fa', 16)) self.right_bar_widget_search_input = QtWidgets.QLineEdit("") self.right_bar_widget_search_input.setPlaceholderText( "输入歌手、歌曲或用户,回车进行搜索") self.right_bar_layout.addWidget(self.search_icon, 0, 0, 1, 1) self.right_bar_layout.addWidget(self.right_bar_widget_search_input, 0, 1, 1, 8) self.right_layout.addWidget(self.right_bar_widget, 0, 0, 1, 9) self.right_bar_widget_search_input.returnPressed.connect( self.Get_song_name) self.right_bar_widget_search_input.setStyleSheet('''QLineEdit{ border:1px solid gray; width:300px; border-radius:10px; padding:2px 4px; }''') self.right_widget.setStyleSheet(''' QWidget#right_widget{ color:#232C51; background:white; border-top:1px solid darkGray; border-bottom:1px solid darkGray; border-right:1px solid darkGray; border-top-right-radius:10px; border-bottom-right-radius:10px; } QLabel#right_lable{ border:none; font-size:16px; font-weight:700; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; } ''') # icon = QtGui.QIcon() # icon.addPixmap(QtGui.QPixmap("ico/瓜板.ico"), QtGui.QIcon.Normal, QtGui.QIcon.Off) # self.setWindowIcon(icon) # self.setToolTip("") self.main_layout.addWidget(self.left_widget, 0, 0, 12, 2) # 左侧部件在第0行第0列,占8行3列 self.main_layout.addWidget(self.right_widget, 0, 2, 12, 10) # 右侧部件在第0行第3列,占8行9列 self.setCentralWidget(self.main_widget) # 设置窗口主部件 self.left_close = QtWidgets.QPushButton("") # 关闭按钮 self.left_visit = QtWidgets.QPushButton("") # 空白按钮 self.left_mini = QtWidgets.QPushButton("") # 最小化按钮 self.left_close.setFixedSize(15, 15) # 设置关闭按钮的大小 self.left_visit.setFixedSize(15, 15) # 设置按钮大小 self.left_mini.setFixedSize(15, 15) # 设置最小化按钮大小 self.left_layout.addWidget(self.left_mini, 0, 0, 1, 1) # 放置最小化按钮 self.left_layout.addWidget(self.left_close, 0, 2, 1, 1) # 放置关闭按钮 self.left_layout.addWidget(self.left_visit, 0, 1, 1, 1) # 放置空白按钮 self.left_close.setStyleSheet( '''QPushButton{background:#F76677;border-radius:5px;}QPushButton:hover{background:red;}''' ) self.left_visit.setStyleSheet( '''QPushButton{background:#F7D674;border-radius:5px;}QPushButton:hover{background:yellow;}''' ) self.left_mini.setStyleSheet( '''QPushButton{background:#6DDF6D;border-radius:5px;}QPushButton:hover{background:green;}''' ) self.left_close.clicked.connect(self.left_close_event) # 添加关闭功能 self.setWindowFlag(QtCore.Qt.FramelessWindowHint) # 隐藏边框 self.setWindowOpacity(0.95) # 设置窗口透明度 # self.setAttribute(QtCore.Qt.WA_TranslucentBackground) # 设置窗口背景透明 self.main_layout.setSpacing(0) # 鼠标长按事件 def mousePressEvent(self, event): if event.button() == QtCore.Qt.LeftButton: self.m_drag = True self.m_DragPosition = event.globalPos() - self.pos() event.accept() self.setCursor(QtGui.QCursor(QtCore.Qt.OpenHandCursor)) # 鼠标移动事件 def mouseMoveEvent(self, QMouseEvent): if QtCore.Qt.LeftButton and self.m_drag: self.move(QMouseEvent.globalPos() - self.m_DragPosition) QMouseEvent.accept() # 鼠标释放事件 def mouseReleaseEvent(self, QMouseEvent): self.m_drag = False self.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor)) def left_close_event(self): self.close() def Get_song_name(self): song_name = self.right_bar_widget_search_input.text() # 提取歌曲id a, song_id = Cloud_Music_API.single_search(song_name) #print(song_id) # 获取url song_url = Cloud_Music_API.song_url(song_id[1]) # 播放音乐 content = QMediaContent(QtCore.QUrl(song_url)) self.player.setMedia(content) self.player.setVolume(30) self.player.play() self.duration = self.player.duration() # 音乐的时长
class MainWindow(QMainWindow, Ui_MainWindow): def __init__(self, *args, **kwargs): super(MainWindow, self).__init__(*args, **kwargs) self.setupUi(self) self.threadpool = QThreadPool() print('Multithreading with maximum %d threads' % self.threadpool.maxThreadCount()) self.player = QMediaPlayer() # Setup the playlist. self.playlist = QMediaPlaylist() self.player.setPlaylist(self.playlist) # Setup the player self.player.durationChanged.connect(self.update_duration) self.player.positionChanged.connect(self.update_position) self.playlist.currentIndexChanged.connect( self.playlist_position_changed) self.player.error.connect(self.erroralert) self.videoWidget = QVideoWidget() self.player.setVideoOutput(self.videoWidget) self.model = PlaylistModel(self.playlist) self.playListView.setModel(self.model) selection_model = self.playListView.selectionModel() selection_model.selectionChanged.connect( self.playlist_selection_changed) self.currentFrame = QVideoFrame() # Connect control buttons/slides for media player. self.playButton.pressed.connect(self.player.play) self.pauseButton.pressed.connect(self.player.pause) self.stopButton.pressed.connect(self.player.stop) layout = QVBoxLayout() layout.addWidget(self.videoWidget) self.viewWidget.setLayout(layout) self.probe = QVideoProbe() self.probe.videoFrameProbed.connect(self.on_videoFrameProbed) self.probe.setSource(self.player) self.timeSlider.valueChanged.connect(self.player.setPosition) self.open_file_action.triggered.connect(self.open_file) # button for save current frame self.saveButton.pressed.connect(self.save_frame) self.setAcceptDrops(True) self.show() def on_videoFrameProbed(self, frame): self.frame = frame def save_frame(self): worker = Worker(self.frame) self.threadpool.start(worker) def dragEnterEvent(self, e): if e.mimeData().hasUrls(): e.acceptProposedAction() 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): path, _ = QFileDialog.getOpenFileName( self, "Open file", "", "mp3 Audio (*.mp3);mp4 Video (*.mp4);Movie files (*.mov);All files (*.*)" ) if path: self.playlist.addMedia(QMediaContent(QUrl.fromLocalFile(path))) self.model.layoutChanged.emit() 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)) # Disable the events to prevent updating triggering a setPosition event (can cause stuttering). self.timeSlider.blockSignals(True) self.timeSlider.setValue(position) self.timeSlider.blockSignals(False) def playlist_selection_changed(self, ix): # We receive a QItemSelection from selectionChanged. i = ix.indexes()[0].row() self.playlist.setCurrentIndex(i) def playlist_position_changed(self, i): if i > -1: ix = self.model.index(i) self.playListView.setCurrentIndex(ix) # self.playlistView.setCurrentIndex(ix) def erroralert(self, *args): print(args)
class GameWindow(QWidget): def __init__(self, parent=None): super(GameWindow,self).__init__(parent) self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.videoWidget = QVideoWidget() self.mediaPlayer.setVideoOutput(self.videoWidget) self.stringLabel = QLabel() self.stringLabel.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum) self.stringLabel.setTextFormat(Qt.RichText) self.stringLabel.setAlignment(Qt.AlignHCenter) layout = QVBoxLayout() layout.addWidget(self.videoWidget) layout.addWidget(self.stringLabel) self.setLayout(layout) self.mediaPlayer.positionChanged.connect(self.positionChanged) def openFile(self, fileName): if fileName != '': self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile(fileName))) def play(self): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.mediaPlayer.pause() else: self.mediaPlayer.play() def playV(self, file, rate, visibility, labelString): self.position = 0 self.startPos = 0 self.duration = 0 self.durChanged = False self.stopPos = False self.openFile(file) self.mediaPlayer.setPlaybackRate(rate) if visibility: self.videoWidget.show() self.stringLabel.show() self.stringLabel.setText(labelString) else: self.videoWidget.hide() self.stringLabel.show() self.stringLabel.setText(labelString) self.play() def closeEvent(self, event): event.ignore() self.mediaPlayer.stop() super(GameWindow, self).closeEvent(event) def positionChanged(self, pos): self.position = pos if not self.durChanged and self.position > 0: self.durationChanged(self.mediaPlayer.duration()) self.durChanged = True if self.startPos > 0 and not self.stopPos and not self.videoWidget.isVisible(): if self.position > self.startPos + 20000: self.play() self.stopPos = True def durationChanged(self, dur): self.duration = dur if self.duration > 40000 and not self.videoWidget.isVisible(): self.startPos = random.randint(5000, self.duration - 25000) self.mediaPlayer.setPosition(self.startPos) def showPoints(self, pointsString): self.videoWidget.hide() self.stringLabel.show() self.stringLabel.setText(pointsString)
class MusicPlayer(QMainWindow): """MusicPlayer houses all of elements that directly interact with the main window.""" def __init__(self, parent=None): """Initialize the QMainWindow widget. The window title, window icon, and window size are initialized here as well as the following widgets: QMediaPlayer, QMediaPlaylist, QMediaContent, QMenuBar, QToolBar, QLabel, QPixmap, QSlider, QDockWidget, QListWidget, QWidget, and QVBoxLayout. The connect signals for relavant widgets are also initialized. """ super(MusicPlayer, self).__init__(parent) self.setWindowTitle('Mosaic') window_icon = utilities.resource_filename('mosaic.images', 'icon.png') self.setWindowIcon(QIcon(window_icon)) self.resize(defaults.Settings().window_size, defaults.Settings().window_size + 63) # Initiates Qt objects to be used by MusicPlayer self.player = QMediaPlayer() self.playlist = QMediaPlaylist() self.playlist_location = defaults.Settings().playlist_path self.content = QMediaContent() self.menu = self.menuBar() self.toolbar = QToolBar() self.art = QLabel() self.pixmap = QPixmap() self.slider = QSlider(Qt.Horizontal) self.duration_label = QLabel() self.playlist_dock = QDockWidget('Playlist', self) self.library_dock = QDockWidget('Media Library', self) self.playlist_view = QListWidget() self.library_view = library.MediaLibraryView() self.library_model = library.MediaLibraryModel() self.preferences = configuration.PreferencesDialog() self.widget = QWidget() self.layout = QVBoxLayout(self.widget) self.duration = 0 self.playlist_dock_state = None self.library_dock_state = None # Sets QWidget() as the central widget of the main window self.setCentralWidget(self.widget) self.layout.setContentsMargins(0, 0, 0, 0) self.art.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored) # Initiates the playlist dock widget and the library dock widget self.addDockWidget(defaults.Settings().dock_position, self.playlist_dock) self.playlist_dock.setWidget(self.playlist_view) self.playlist_dock.setVisible(defaults.Settings().playlist_on_start) self.playlist_dock.setFeatures(QDockWidget.DockWidgetClosable) self.addDockWidget(defaults.Settings().dock_position, self.library_dock) self.library_dock.setWidget(self.library_view) self.library_dock.setVisible(defaults.Settings().media_library_on_start) self.library_dock.setFeatures(QDockWidget.DockWidgetClosable) self.tabifyDockWidget(self.playlist_dock, self.library_dock) # Sets the range of the playback slider and sets the playback mode as looping self.slider.setRange(0, self.player.duration() / 1000) self.playlist.setPlaybackMode(QMediaPlaylist.Sequential) # OSX system menu bar causes conflicts with PyQt5 menu bar if sys.platform == 'darwin': self.menu.setNativeMenuBar(False) # Initiates Settings in the defaults module to give access to settings.toml defaults.Settings() # Signals that connect to other methods when they're called self.player.metaDataChanged.connect(self.display_meta_data) self.slider.sliderMoved.connect(self.seek) self.player.durationChanged.connect(self.song_duration) self.player.positionChanged.connect(self.song_position) self.player.stateChanged.connect(self.set_state) self.playlist_view.itemActivated.connect(self.activate_playlist_item) self.library_view.activated.connect(self.open_media_library) self.playlist.currentIndexChanged.connect(self.change_index) self.playlist.mediaInserted.connect(self.initialize_playlist) self.playlist_dock.visibilityChanged.connect(self.dock_visiblity_change) self.library_dock.visibilityChanged.connect(self.dock_visiblity_change) self.preferences.dialog_media_library.media_library_line.textChanged.connect(self.change_media_library_path) self.preferences.dialog_view_options.dropdown_box.currentIndexChanged.connect(self.change_window_size) self.art.mousePressEvent = self.press_playback # Creating the menu controls, media controls, and window size of the music player self.menu_controls() self.media_controls() self.load_saved_playlist() def menu_controls(self): """Initiate the menu bar and add it to the QMainWindow widget.""" self.file = self.menu.addMenu('File') self.edit = self.menu.addMenu('Edit') self.playback = self.menu.addMenu('Playback') self.view = self.menu.addMenu('View') self.help_ = self.menu.addMenu('Help') self.file_menu() self.edit_menu() self.playback_menu() self.view_menu() self.help_menu() def media_controls(self): """Create the bottom toolbar and controls used for media playback.""" self.addToolBar(Qt.BottomToolBarArea, self.toolbar) self.toolbar.setMovable(False) play_icon = utilities.resource_filename('mosaic.images', 'md_play.png') self.play_action = QAction(QIcon(play_icon), 'Play', self) self.play_action.triggered.connect(self.player.play) stop_icon = utilities.resource_filename('mosaic.images', 'md_stop.png') self.stop_action = QAction(QIcon(stop_icon), 'Stop', self) self.stop_action.triggered.connect(self.player.stop) previous_icon = utilities.resource_filename('mosaic.images', 'md_previous.png') self.previous_action = QAction(QIcon(previous_icon), 'Previous', self) self.previous_action.triggered.connect(self.previous) next_icon = utilities.resource_filename('mosaic.images', 'md_next.png') self.next_action = QAction(QIcon(next_icon), 'Next', self) self.next_action.triggered.connect(self.playlist.next) repeat_icon = utilities.resource_filename('mosaic.images', 'md_repeat_none.png') self.repeat_action = QAction(QIcon(repeat_icon), 'Repeat', self) self.repeat_action.setShortcut('R') self.repeat_action.triggered.connect(self.repeat_song) self.toolbar.addAction(self.play_action) self.toolbar.addAction(self.stop_action) self.toolbar.addAction(self.previous_action) self.toolbar.addAction(self.next_action) self.toolbar.addAction(self.repeat_action) self.toolbar.addWidget(self.slider) self.toolbar.addWidget(self.duration_label) def file_menu(self): """Add a file menu to the menu bar. The file menu houses the Open File, Open Multiple Files, Open Playlist, Open Directory, and Exit Application menu items. """ self.open_action = QAction('Open File', self) self.open_action.setShortcut('O') self.open_action.triggered.connect(self.open_file) self.open_multiple_files_action = QAction('Open Multiple Files', self) self.open_multiple_files_action.setShortcut('M') self.open_multiple_files_action.triggered.connect(self.open_multiple_files) self.open_playlist_action = QAction('Open Playlist', self) self.open_playlist_action.setShortcut('CTRL+P') self.open_playlist_action.triggered.connect(self.open_playlist) self.open_directory_action = QAction('Open Directory', self) self.open_directory_action.setShortcut('D') self.open_directory_action.triggered.connect(self.open_directory) self.save_playlist_action = QAction('Save Playlist', self) self.save_playlist_action.setShortcut('CTRL+S') self.save_playlist_action.triggered.connect(self.save_playlist) self.exit_action = QAction('Quit', self) self.exit_action.setShortcut('CTRL+Q') self.exit_action.triggered.connect(self.closeEvent) self.file.addAction(self.open_action) self.file.addAction(self.open_multiple_files_action) self.file.addAction(self.open_playlist_action) self.file.addAction(self.open_directory_action) self.file.addSeparator() self.file.addAction(self.save_playlist_action) self.file.addSeparator() self.file.addAction(self.exit_action) def edit_menu(self): """Add an edit menu to the menu bar. The edit menu houses the preferences item that opens a preferences dialog that allows the user to customize features of the music player. """ self.preferences_action = QAction('Preferences', self) self.preferences_action.setShortcut('CTRL+SHIFT+P') self.preferences_action.triggered.connect(lambda: self.preferences.exec_()) self.edit.addAction(self.preferences_action) def playback_menu(self): """Add a playback menu to the menu bar. The playback menu houses """ self.play_playback_action = QAction('Play', self) self.play_playback_action.setShortcut('P') self.play_playback_action.triggered.connect(self.player.play) self.stop_playback_action = QAction('Stop', self) self.stop_playback_action.setShortcut('S') self.stop_playback_action.triggered.connect(self.player.stop) self.previous_playback_action = QAction('Previous', self) self.previous_playback_action.setShortcut('B') self.previous_playback_action.triggered.connect(self.previous) self.next_playback_action = QAction('Next', self) self.next_playback_action.setShortcut('N') self.next_playback_action.triggered.connect(self.playlist.next) self.playback.addAction(self.play_playback_action) self.playback.addAction(self.stop_playback_action) self.playback.addAction(self.previous_playback_action) self.playback.addAction(self.next_playback_action) def view_menu(self): """Add a view menu to the menu bar. The view menu houses the Playlist, Media Library, Minimalist View, and Media Information menu items. The Playlist item toggles the playlist dock into and out of view. The Media Library items toggles the media library dock into and out of view. The Minimalist View item resizes the window and shows only the menu bar and player controls. The Media Information item opens a dialog that shows information relevant to the currently playing song. """ self.dock_action = self.playlist_dock.toggleViewAction() self.dock_action.setShortcut('CTRL+ALT+P') self.library_dock_action = self.library_dock.toggleViewAction() self.library_dock_action.setShortcut('CTRL+ALT+L') self.minimalist_view_action = QAction('Minimalist View', self) self.minimalist_view_action.setShortcut('CTRL+ALT+M') self.minimalist_view_action.setCheckable(True) self.minimalist_view_action.triggered.connect(self.minimalist_view) self.view_media_info_action = QAction('Media Information', self) self.view_media_info_action.setShortcut('CTRL+SHIFT+M') self.view_media_info_action.triggered.connect(self.media_information_dialog) self.view.addAction(self.dock_action) self.view.addAction(self.library_dock_action) self.view.addSeparator() self.view.addAction(self.minimalist_view_action) self.view.addSeparator() self.view.addAction(self.view_media_info_action) def help_menu(self): """Add a help menu to the menu bar. The help menu houses the about dialog that shows the user information related to the application. """ self.about_action = QAction('About', self) self.about_action.setShortcut('H') self.about_action.triggered.connect(lambda: about.AboutDialog().exec_()) self.help_.addAction(self.about_action) def open_file(self): """Open the selected file and add it to a new playlist.""" filename, success = QFileDialog.getOpenFileName(self, 'Open File', '', 'Audio (*.mp3 *.flac)', '', QFileDialog.ReadOnly) if success: file_info = QFileInfo(filename).fileName() playlist_item = QListWidgetItem(file_info) self.playlist.clear() self.playlist_view.clear() self.playlist.addMedia(QMediaContent(QUrl().fromLocalFile(filename))) self.player.setPlaylist(self.playlist) playlist_item.setToolTip(file_info) self.playlist_view.addItem(playlist_item) self.playlist_view.setCurrentRow(0) self.player.play() def open_multiple_files(self): """Open the selected files and add them to a new playlist.""" filenames, success = QFileDialog.getOpenFileNames(self, 'Open Multiple Files', '', 'Audio (*.mp3 *.flac)', '', QFileDialog.ReadOnly) if success: self.playlist.clear() self.playlist_view.clear() for file in natsort.natsorted(filenames, alg=natsort.ns.PATH): file_info = QFileInfo(file).fileName() playlist_item = QListWidgetItem(file_info) self.playlist.addMedia(QMediaContent(QUrl().fromLocalFile(file))) self.player.setPlaylist(self.playlist) playlist_item.setToolTip(file_info) self.playlist_view.addItem(playlist_item) self.playlist_view.setCurrentRow(0) self.player.play() def open_playlist(self): """Load an M3U or PLS file into a new playlist.""" playlist, success = QFileDialog.getOpenFileName(self, 'Open Playlist', '', 'Playlist (*.m3u *.pls)', '', QFileDialog.ReadOnly) if success: playlist = QUrl.fromLocalFile(playlist) self.playlist.clear() self.playlist_view.clear() self.playlist.load(playlist) self.player.setPlaylist(self.playlist) for song_index in range(self.playlist.mediaCount()): file_info = self.playlist.media(song_index).canonicalUrl().fileName() playlist_item = QListWidgetItem(file_info) playlist_item.setToolTip(file_info) self.playlist_view.addItem(playlist_item) self.playlist_view.setCurrentRow(0) self.player.play() def save_playlist(self): """Save the media in the playlist dock as a new M3U playlist.""" playlist, success = QFileDialog.getSaveFileName(self, 'Save Playlist', '', 'Playlist (*.m3u)', '') if success: saved_playlist = "{}.m3u" .format(playlist) self.playlist.save(QUrl().fromLocalFile(saved_playlist), "m3u") def load_saved_playlist(self): """Load the saved playlist if user setting permits.""" saved_playlist = "{}/.m3u" .format(self.playlist_location) if os.path.exists(saved_playlist): playlist = QUrl().fromLocalFile(saved_playlist) self.playlist.load(playlist) self.player.setPlaylist(self.playlist) for song_index in range(self.playlist.mediaCount()): file_info = self.playlist.media(song_index).canonicalUrl().fileName() playlist_item = QListWidgetItem(file_info) playlist_item.setToolTip(file_info) self.playlist_view.addItem(playlist_item) self.playlist_view.setCurrentRow(0) def open_directory(self): """Open the selected directory and add the files within to an empty playlist.""" directory = QFileDialog.getExistingDirectory(self, 'Open Directory', '', QFileDialog.ReadOnly) if directory: self.playlist.clear() self.playlist_view.clear() for dirpath, __, files in os.walk(directory): for filename in natsort.natsorted(files, alg=natsort.ns.PATH): file = os.path.join(dirpath, filename) if filename.endswith(('mp3', 'flac')): self.playlist.addMedia(QMediaContent(QUrl().fromLocalFile(file))) playlist_item = QListWidgetItem(filename) playlist_item.setToolTip(filename) self.playlist_view.addItem(playlist_item) self.player.setPlaylist(self.playlist) self.playlist_view.setCurrentRow(0) self.player.play() def open_media_library(self, index): """Open a directory or file from the media library into an empty playlist.""" self.playlist.clear() self.playlist_view.clear() if self.library_model.fileName(index).endswith(('mp3', 'flac')): self.playlist.addMedia(QMediaContent(QUrl().fromLocalFile(self.library_model.filePath(index)))) self.playlist_view.addItem(self.library_model.fileName(index)) elif self.library_model.isDir(index): directory = self.library_model.filePath(index) for dirpath, __, files in os.walk(directory): for filename in natsort.natsorted(files, alg=natsort.ns.PATH): file = os.path.join(dirpath, filename) if filename.endswith(('mp3', 'flac')): self.playlist.addMedia(QMediaContent(QUrl().fromLocalFile(file))) playlist_item = QListWidgetItem(filename) playlist_item.setToolTip(filename) self.playlist_view.addItem(playlist_item) self.player.setPlaylist(self.playlist) self.player.play() def display_meta_data(self): """Display the current song's metadata in the main window. If the current song contains metadata, its cover art is extracted and shown in the main window while the track number, artist, album, and track title are shown in the window title. """ if self.player.isMetaDataAvailable(): file_path = self.player.currentMedia().canonicalUrl().toLocalFile() (album, artist, title, track_number, *__, artwork) = metadata.metadata(file_path) try: self.pixmap.loadFromData(artwork) except TypeError: self.pixmap = QPixmap(artwork) meta_data = '{} - {} - {} - {}' .format(track_number, artist, album, title) self.setWindowTitle(meta_data) self.art.setScaledContents(True) self.art.setPixmap(self.pixmap) self.layout.addWidget(self.art) def initialize_playlist(self, start): """Display playlist and reset playback mode when media inserted into playlist.""" if start == 0: if self.library_dock.isVisible(): self.playlist_dock.setVisible(True) self.playlist_dock.show() self.playlist_dock.raise_() if self.playlist.playbackMode() != QMediaPlaylist.Sequential: self.playlist.setPlaybackMode(QMediaPlaylist.Sequential) repeat_icon = utilities.resource_filename('mosaic.images', 'md_repeat_none.png') self.repeat_action.setIcon(QIcon(repeat_icon)) def press_playback(self, event): """Change the playback of the player on cover art mouse event. When the cover art is clicked, the player will play the media if the player is either paused or stopped. If the media is playing, the media is set to pause. """ if event.button() == 1 and configuration.Playback().cover_art_playback.isChecked(): if (self.player.state() == QMediaPlayer.StoppedState or self.player.state() == QMediaPlayer.PausedState): self.player.play() elif self.player.state() == QMediaPlayer.PlayingState: self.player.pause() def seek(self, seconds): """Set the position of the song to the position dragged to by the user.""" self.player.setPosition(seconds * 1000) def song_duration(self, duration): """Set the slider to the duration of the currently played media.""" duration /= 1000 self.duration = duration self.slider.setMaximum(duration) def song_position(self, progress): """Move the horizontal slider in sync with the duration of the song. The progress is relayed to update_duration() in order to display the time label next to the slider. """ progress /= 1000 if not self.slider.isSliderDown(): self.slider.setValue(progress) self.update_duration(progress) def update_duration(self, current_duration): """Calculate the time played and the length of the song. Both of these times are sent to duration_label() in order to display the times on the toolbar. """ duration = self.duration if current_duration or duration: time_played = QTime((current_duration / 3600) % 60, (current_duration / 60) % 60, (current_duration % 60), (current_duration * 1000) % 1000) song_length = QTime((duration / 3600) % 60, (duration / 60) % 60, (duration % 60), (duration * 1000) % 1000) if duration > 3600: time_format = "hh:mm:ss" else: time_format = "mm:ss" time_display = "{} / {}" .format(time_played.toString(time_format), song_length.toString(time_format)) else: time_display = "" self.duration_label.setText(time_display) def set_state(self, state): """Change the icon in the toolbar in relation to the state of the player. The play icon changes to the pause icon when a song is playing and the pause icon changes back to the play icon when either paused or stopped. """ if self.player.state() == QMediaPlayer.PlayingState: pause_icon = utilities.resource_filename('mosaic.images', 'md_pause.png') self.play_action.setIcon(QIcon(pause_icon)) self.play_action.triggered.connect(self.player.pause) elif (self.player.state() == QMediaPlayer.PausedState or self.player.state() == QMediaPlayer.StoppedState): self.play_action.triggered.connect(self.player.play) play_icon = utilities.resource_filename('mosaic.images', 'md_play.png') self.play_action.setIcon(QIcon(play_icon)) def previous(self): """Move to the previous song in the playlist. Moves to the previous song in the playlist if the current song is less than five seconds in. Otherwise, restarts the current song. """ if self.player.position() <= 5000: self.playlist.previous() else: self.player.setPosition(0) def repeat_song(self): """Set the current media to repeat and change the repeat icon accordingly. There are four playback modes: repeat none, repeat all, repeat once, and shuffle. Clicking the repeat button cycles through each playback mode. """ if self.playlist.playbackMode() == QMediaPlaylist.Sequential: self.playlist.setPlaybackMode(QMediaPlaylist.Loop) repeat_on_icon = utilities.resource_filename('mosaic.images', 'md_repeat_all.png') self.repeat_action.setIcon(QIcon(repeat_on_icon)) elif self.playlist.playbackMode() == QMediaPlaylist.Loop: self.playlist.setPlaybackMode(QMediaPlaylist.CurrentItemInLoop) repeat_on_icon = utilities.resource_filename('mosaic.images', 'md_repeat_once.png') self.repeat_action.setIcon(QIcon(repeat_on_icon)) elif self.playlist.playbackMode() == QMediaPlaylist.CurrentItemInLoop: self.playlist.setPlaybackMode(QMediaPlaylist.Random) repeat_icon = utilities.resource_filename('mosaic.images', 'md_shuffle.png') self.repeat_action.setIcon(QIcon(repeat_icon)) elif self.playlist.playbackMode() == QMediaPlaylist.Random: self.playlist.setPlaybackMode(QMediaPlaylist.Sequential) repeat_icon = utilities.resource_filename('mosaic.images', 'md_repeat_none.png') self.repeat_action.setIcon(QIcon(repeat_icon)) def activate_playlist_item(self, item): """Set the active media to the playlist item dobule-clicked on by the user.""" current_index = self.playlist_view.row(item) if self.playlist.currentIndex() != current_index: self.playlist.setCurrentIndex(current_index) if self.player.state() != QMediaPlayer.PlayingState: self.player.play() def change_index(self, row): """Highlight the row in the playlist of the active media.""" self.playlist_view.setCurrentRow(row) def minimalist_view(self): """Resize the window to only show the menu bar and audio controls.""" if self.minimalist_view_action.isChecked(): if self.playlist_dock.isVisible(): self.playlist_dock_state = True if self.library_dock.isVisible(): self.library_dock_state = True self.library_dock.close() self.playlist_dock.close() QTimer.singleShot(10, lambda: self.resize(500, 0)) else: self.resize(defaults.Settings().window_size, defaults.Settings().window_size + 63) if self.library_dock_state: self.library_dock.setVisible(True) if self.playlist_dock_state: self.playlist_dock.setVisible(True) def dock_visiblity_change(self, visible): """Change the size of the main window when the docks are toggled.""" if visible and self.playlist_dock.isVisible() and not self.library_dock.isVisible(): self.resize(defaults.Settings().window_size + self.playlist_dock.width() + 6, self.height()) elif visible and not self.playlist_dock.isVisible() and self.library_dock.isVisible(): self.resize(defaults.Settings().window_size + self.library_dock.width() + 6, self.height()) elif visible and self.playlist_dock.isVisible() and self.library_dock.isVisible(): self.resize(defaults.Settings().window_size + self.library_dock.width() + 6, self.height()) elif (not visible and not self.playlist_dock.isVisible() and not self.library_dock.isVisible()): self.resize(defaults.Settings().window_size, defaults.Settings().window_size + 63) def media_information_dialog(self): """Show a dialog of the current song's metadata.""" if self.player.isMetaDataAvailable(): file_path = self.player.currentMedia().canonicalUrl().toLocalFile() else: file_path = None dialog = information.InformationDialog(file_path) dialog.exec_() def change_window_size(self): """Change the window size of the music player.""" self.playlist_dock.close() self.library_dock.close() self.resize(defaults.Settings().window_size, defaults.Settings().window_size + 63) def change_media_library_path(self, path): """Change the media library path to the new path selected in the preferences dialog.""" self.library_model.setRootPath(path) self.library_view.setModel(self.library_model) self.library_view.setRootIndex(self.library_model.index(path)) def closeEvent(self, event): """Override the PyQt close event in order to handle save playlist on close.""" playlist = "{}/.m3u" .format(self.playlist_location) if defaults.Settings().save_playlist_on_close: self.playlist.save(QUrl().fromLocalFile(playlist), "m3u") else: if os.path.exists(playlist): os.remove(playlist) QApplication.quit()
class jaabaGUI(QMainWindow): """ controller for the blob labeling GUI""" def __init__(self,parent=None): self.debugMode = True self.debugVideoPath = '/Users/071cht/Desktop/Lab/jaabagui/testt.mjpeg.avi' QMainWindow.__init__(self,parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.installEventFilter(self) self.setFocusPolicy(Qt.StrongFocus) #add new slider # self.positionSlider=QSlider(Qt.Horizontal) # self.positionSlider.setGeometry (800,800,100,30) # self.positionSlider.setRange(0, 0) # self.positionSlider.sliderMoved.connect(self.setPosition) #setup Video #video player self.mediaPlayer1 = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.mediaPlayer2 = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.mediaPlayer2.setNotifyInterval(10) #self.mediaPlayer.metaDataChanged.connect(self.metaDataChanged) self.mediaPlayer1.durationChanged.connect(self.durationChanged) self.mediaPlayer1.positionChanged.connect(self.positionChanged) self.mediaPlayer2.positionChanged.connect(self.positionChanged) #self.mediaPlayer2.positionChanged.connect(self.paintEvent) #visualizetion self.scene = QGraphicsScene() self.ui.graphicsView.setScene(self.scene) #self.scene.setBackgroundBrush(Qt.black) self.videoItem1 = QGraphicsVideoItem() self.videoItem2 = Video() self.scene.addItem(self.videoItem1) self.scene.addItem(self.videoItem2) self.mediaPlayer1.setVideoOutput(self.videoItem1) self.mediaPlayer2.setVideoOutput(self.videoItem2) #slider bar self.ui.horizontalSlider.setRange(0, 0) self.ui.horizontalSlider.sliderMoved.connect(self.setPosition) # self.ui.horizontalSlider.sliderPressed.connect(self.sliderPressed) #draw on video self.flyCanvas= TargetView() self.scene.addItem(self.flyCanvas) #give reference to target view self.flyCanvas.setWindowReference(self) #lineEdit signals: self.ui.lineEdit.returnPressed.connect(self.lineEditChanged) #callbacks self.ui.actionQuit.triggered.connect(self.quit) self.ui.actionLoad_Project.triggered.connect(self.loadVideo) self.ui.actionImport_Labels.triggered.connect(self.loadLabels) #self.ui.buttonPlay.clicked[bool].connect(self.setToggleText) self.ui.buttonPlay.clicked.connect(self.play) self.ui.actionSave.triggered.connect(self.saveLabels) ## print self.ui.graphicsView.sizeHint() #behavior Button self.ui.buttonBehavior.clicked.connect(self.behaviorButtonClick) self.ui.buttonNone.clicked.connect(self.noneButtonClick) #initialization self.loaded = False self.videoFilename = None self.frame_count=None self.width=None self.height=None self.frame_trans=None self.previous_frame=0 self.current_frame=0 self.behaviorButtonStart = False self.noneButtonStart = False self.currentFly=1 #initialize flyInfo #self.setCurrentFly(self.currentFly) # register flyid changed callback self.flyCanvas.onCurrentFlyIdChanged(self.currentFlyIdChangedCallback) self.flyCanvas.setCurrentFlyId(self.currentFly) # when double click on video, change fly id in target view self.videoItem2.onDoubleClick(self.flyCanvas.setCurrentFlyIdByXY) ######################## # DEBUG PART HERE!!!!! # ######################## if (self.debugMode): self.debugLoadVideo() # add label UI related when load video def showEvent(self, evt): super(jaabaGUI, self).showEvent(evt) ##### HERE THE WINDOW IS LOADED!!!!!!!! # self.loadLabelUI() def loadLabelUI(self): #labels self.labelScene = QGraphicsScene() self.ui.graphLabels.setScene(self.labelScene) # the size is only accurate after the window fully displayed labelUIWidth = self.ui.graphLabels.width() labelUIHeight = self.ui.graphLabels.height()-1 self.labelScene.setSceneRect(0,0,labelUIWidth,labelUIHeight) self.labelUI = LabelUI() # visiableWidth = 850 # height = 30 # visiableFrameNum = 850 self.labelUI.setWidthPerFrame(850.0/850.0) # print '850/500',850.0/850.0b # print 'length_perframe is ', self.labelUI.widthPerFrame # 850 is the original length of graphLabel total_length= self.labelUI.widthPerFrame * self.frame_count self.labelUI.setVisiableSize(total_length,30) # set start position self.labelUI.setPos(labelUIWidth/2,0) print 'frame_count is ', self.frame_count print 'total length is', total_length self.labelScene.addItem(self.labelUI) # middle line ui self.labelUIMiddleLine = LabelUIMiddleLine() self.labelScene.addItem(self.labelUIMiddleLine) self.labelUIMiddleLine.setPos(labelUIWidth/2,0) # self.labelUI.setPos(QPointF(-100,0)) self.writeLog('Label UI loaded') def eventFilter(self, obj, event): if (event.type() == PyQt5.QtCore.QEvent.KeyPress): # http://qt-project.org/doc/qt-4.8/qt.html#Key-enum key = event.key() if (key == Qt.Key_Up) : curr_frame= int(float(self.ui.lineEdit.text())) curr_frame= curr_frame-30 media_position= int(round(curr_frame*self.frame_trans)) # print curr_frame, media_position self.mediaPlayer1.setPosition(media_position) self.mediaPlayer2.setPosition(media_position) # print 'down -30' elif (key == Qt.Key_Right): curr_frame= int(float(self.ui.lineEdit.text())) # print 'right +1' # print curr_frame curr_frame= curr_frame+1 media_position= int(round(curr_frame*self.frame_trans)) # print 'curr_frame',curr_frame # print 'frame_trans',self.frame_trans # print ' curr_frame*self.frame_trans',curr_frame*self.frame_trans # print 'media_position',media_position # print curr_frame, media_position self.mediaPlayer1.setPosition(media_position) self.mediaPlayer2.setPosition(media_position) # self.mediaPlayerPositionChanged(media_position) elif (key == Qt.Key_Left): curr_frame= int(float(self.ui.lineEdit.text())) curr_frame= curr_frame-1 media_position= int(round(curr_frame*self.frame_trans)) self.mediaPlayer1.setPosition(media_position) self.mediaPlayer2.setPosition(media_position) # print 'left -1' elif (key == Qt.Key_Down): curr_frame= int(float(self.ui.lineEdit.text())) curr_frame= curr_frame+30 media_position= int(round(curr_frame*self.frame_trans)) self.mediaPlayer1.setPosition(media_position) self.mediaPlayer2.setPosition(media_position) # print 'up +30' return True return False # ###actions starts from here### def quit(self): QApplication.quit() def loadVideo(self): # print QMediaPlayer.supportedMimeTypes() self.writeLog("Loading video...") self.videoFilename = QFileDialog.getOpenFileName(self, 'Open File', '.')[0] if not self.videoFilename: self.writeLog("User cancelled - no video loaded") return else: cap=cv2.VideoCapture(self.videoFilename) self.frame_count=cap.get(cv2.CAP_PROP_FRAME_COUNT) self.width=cap.get(3) self.height=cap.get(4) self.mediaPlayer2.setMedia(QMediaContent(QUrl.fromLocalFile(self.videoFilename ))) self.mediaPlayer1.setMedia(QMediaContent(QUrl.fromLocalFile(self.videoFilename ))) self.ui.buttonPlay.setEnabled(True) # self.mediaPlayer2.setVideoOutput(self.videoItem2) # self.mediaPlayer1.setVideoOutput(self.videoItem1) # size= self.videoItem2.nativeSize() # # print size ## print self.mediaPlayer.duration() ## print self.mediaPlayer.metaData() self.writeLog("Video loaded!") # init label related ui self.loadLabelUI() def debugLoadVideo(self): self.videoFilename = self.debugVideoPath cap=cv2.VideoCapture(self.videoFilename) self.frame_count=cap.get(cv2.CAP_PROP_FRAME_COUNT) self.width=cap.get(3) self.height=cap.get(4) self.mediaPlayer2.setMedia(QMediaContent(QUrl.fromLocalFile(self.videoFilename ))) self.mediaPlayer1.setMedia(QMediaContent(QUrl.fromLocalFile(self.videoFilename ))) self.ui.buttonPlay.setEnabled(True) self.writeLog("Video loaded!") QTimer.singleShot(1000, self.loadLabelUI) def play(self): self.videoItem1.setAspectRatioMode(0) self.videoItem2.setAspectRatioMode(0) self.scene.setSceneRect(0,0,self.ui.graphicsView.width(),self.ui.graphicsView.height()) self.videoItem1.setSize(QSizeF(self.ui.graphicsView.width()/2,self.ui.graphicsView.height())) self.videoItem2.setSize(QSizeF(self.ui.graphicsView.width()/2,self.ui.graphicsView.height())) self.videoItem1.setPos(QPointF(0,0)) self.videoItem2.setPos(QPointF(self.ui.graphicsView.width()/2,0)) self.flyCanvas.setPos(QPointF(self.ui.graphicsView.width()/2,0)) # custom function setXYScale self.videoItem2.setXYScale(self.width,self.height,self.ui.graphicsView.width()/2,self.ui.graphicsView.height()) self.flyCanvas.setXYScale(self.width,self.height,self.ui.graphicsView.width()/2,self.ui.graphicsView.height()) if self.mediaPlayer1.state() == QMediaPlayer.PlayingState: self.ui.buttonPlay.setIcon(self.ui.style().standardIcon(PyQt5.QtWidgets.QStyle.SP_MediaPlay)) self.ui.buttonPlay.setText("Play") self.mediaPlayer1.pause() self.writeLog("Video paused") else: self.ui.buttonPlay.setIcon(self.ui.style().standardIcon(PyQt5.QtWidgets.QStyle.SP_MediaPause)) self.ui.buttonPlay.setText("Stop") self.mediaPlayer1.play() self.writeLog("Playing video") if self.mediaPlayer2.state() == QMediaPlayer.PlayingState: self.mediaPlayer2.pause() else: self.mediaPlayer2.play() def loadLabels(self): self.writeLog("Loading labels from file...") self.labelFilename = QFileDialog.getOpenFileName(self, 'Open File', '.')[0] self.labelUI.labelData = pickle.load(open(self.labelFilename,"rb")) self.writeLog("Label loaded from file:" + self.labelFilename) def saveLabels(self): # Now it can only save to current file. Will add an poput window to choose path later pickle.dump( self.labelUI.labelData, open( "newLabels.p", "wb" ) ) def setPosition(self, position): self.mediaPlayer1.setPosition(position) self.mediaPlayer2.setPosition(position) # when position of media changed, set slider and text box accordingly. def positionChanged(self, position): #test change labelui position # self.labelUI.startLabel(); # self.labelUI.update() previous_frame= self.previous_frame curr_frame= int(round(position/self.frame_trans)) self.current_frame=curr_frame frame_change= previous_frame-curr_frame move_width= frame_change * self.labelUI.widthPerFrame self.previous_frame= curr_frame self.labelUI.moveBy(move_width,0) self.labelUI.setCurrentFrame(curr_frame) # enforce labelUI paint once self.labelUI.update() # self.labelUI.setPos(self.labelUI.mapToParent(1,0)); # self.labelUI.update() # # print 'triggered position' # # print position # # print 'cur position' # # print self.mediaPlayer2.position() self.updateLineEdit(position) self.updateSliderAndGraph(position) # self.ui.horizontalSlider.setValue(position) # if isinstance(self.frame_trans,float): # # # print type(position),position # # # print type(self.frame_trans),self.frame_trans # # # print position/self.frame_trans # self.ui.lineEdit.setText(str(int(round(position/self.frame_trans)))) # self.flyCanvas.getFrame(int(round(position/self.frame_trans))) # self.flyCanvas.isManualCalled = True; # self.flyCanvas.update() # self.writeLog(str(position)) # # self.updateMediaControlUI(position) # # self.flyCanvas.update() def updateSliderAndGraph(self, position): self.ui.horizontalSlider.setValue(position) if isinstance(self.frame_trans,float): self.flyCanvas.getFrame(int(round(position/self.frame_trans))) self.flyCanvas.isManualCalled = True self.flyCanvas.update() #self.writeLog(str(position)) def updateLineEdit(self, position): # # print self.width # # print self.height if isinstance(self.frame_trans,float): # # print type(position),position # # print type(self.frame_trans),self.frame_trans # # print position/self.frame_trans self.ui.lineEdit.setText(str(int(round(position/self.frame_trans)))) def durationChanged(self, duration): self.ui.horizontalSlider.setRange(0, duration) self.frame_trans=self.mediaPlayer1.duration()/self.frame_count ## print self.frame_trans #def eventFilter(self,source,event): #if (event.type()==PyQt5.QtCore.QEvent.MousePress and source is self.videoItem2): # pos=event.pos() # # print('mouse position: (%d,%d)' % (pos.x(),pos.y())) # return PyQt5.QtGui.QWidget.eventFilter(self, source, event) def writeLog(self,text): self.ui.log.setText(text) # def eventFilter (self.ui.lineEdit,event): # if event.type()==PyQt5.QtCore.QEvent def lineEditChanged(self): #set position of media curr_frame= int(float(self.ui.lineEdit.text())) media_position= int(round(curr_frame*self.frame_trans)) self.mediaPlayer1.setPosition(media_position) self.mediaPlayer2.setPosition(media_position) # print 'setPosition' # print media_position # print 'after set' # print self.mediaPlayer2.position() # self.updateSliderAndGraph(media_position) def behaviorButtonClick(self): # flip flag self.behaviorButtonStart = not self.behaviorButtonStart # check click to start or stop if (self.behaviorButtonStart): # start labeling self.labelUI.startLabel(self.ui.comboBox.currentIndex(),'',self.current_frame) self.writeLog('start labeling') else: # stop lableing self.labelUI.stopLabel() self.writeLog('stop labeling') def noneButtonClick(self): # flip flag self.noneButtonStart = not self.noneButtonStart # check click to start or stop if (self.noneButtonStart): # start labeling self.labelUI.startLabel(self.ui.comboBox.currentIndex(),'_none',self.current_frame) self.writeLog('start labeling') else: # stop lableing self.labelUI.stopLabel() self.writeLog('stop labeling') # set CurrentFly when fly changed! def setCurrentFly(self,fly): self.currentFly = fly self.ui.flyInfo.setPlainText('FlyID:' + str(self.currentFly)) self.flyCanvas.currentFly=fly def currentFlyIdChangedCallback(self,fly): print 'callback!!!!!'; self.currentFly = fly self.ui.flyInfo.setPlainText('FlyID:' + str(self.currentFly))
class VideoWindow(QMainWindow): def __init__(self, app, parent=None): super(VideoWindow, self).__init__(parent) self.app = app self.setWindowTitle("sofa") self.setWindowIcon(QIcon('src/static/img/tofu.png')) self.rate = 1 self.isNewMark = False self.openedFile = None self.initUI() self.set_default_shortcuts() self.shortcuts = {} self.comm = SignalBus.instance() def initUI(self): videoWidget = self.create_player() self.errorLabel = QLabel() self.errorLabel.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum) self.create_menu_bar() self.wid = QWidget(self) self.setCentralWidget(self.wid) self.set_layout(videoWidget, self.wid) self.mediaPlayer.setVideoOutput(videoWidget) self.mediaPlayer.stateChanged.connect(self.mediaStateChanged) self.mediaPlayer.positionChanged.connect(self.positionChanged) self.mediaPlayer.durationChanged.connect(self.durationChanged) self.mediaPlayer.error.connect(self.handleError) def create_player(self): self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface) videoWidget = QVideoWidget() self.clipsWidget = BadClipsWidget() self.create_control() self.playButton.clicked.connect(self.play) self.speedUpButton.clicked.connect(self.speed) self.slowDownButton.clicked.connect(self.slow) self.adv3Button.clicked.connect(partial(self.advance, 3)) self.goBack3Button.clicked.connect(partial(self.back, 3)) self.advanceButton.clicked.connect(partial(self.advance, 10)) self.goBackButton.clicked.connect(partial(self.back, 10)) self.positionSlider.sliderMoved.connect(self.setPosition) self.cutButton.clicked.connect(self.createMark) return videoWidget def set_default_shortcuts(self): self.playButton.setShortcut(QKeySequence(Qt.Key_Space)) self.speedUpButton.setShortcut(QKeySequence(Qt.Key_Up)) self.slowDownButton.setShortcut(QKeySequence(Qt.Key_Down)) self.advanceButton.setShortcut(QKeySequence(Qt.Key_Right)) self.goBackButton.setShortcut(QKeySequence(Qt.Key_Left)) self.cutButton.setShortcut(QKeySequence(Qt.Key_C)) def create_control(self): self.playButton = _create_button( self.style().standardIcon(QStyle.SP_MediaPlay)) self.speedUpButton = _create_button( self.style().standardIcon(QStyle.SP_MediaSeekForward)) self.slowDownButton = _create_button( self.style().standardIcon(QStyle.SP_MediaSeekBackward)) self.adv3Button = _create_button( self.style().standardIcon(QStyle.SP_ArrowRight)) self.advanceButton = _create_button( self.style().standardIcon(QStyle.SP_MediaSkipForward)) self.goBack3Button = _create_button( self.style().standardIcon(QStyle.SP_ArrowLeft)) self.goBackButton = _create_button( self.style().standardIcon(QStyle.SP_MediaSkipBackward)) self.cutButton = _create_button(self.style().standardIcon( QStyle.SP_MessageBoxCritical)) self.timeBox = QLabel(format_time(0), self) self.timeBox.setAlignment(Qt.AlignCenter) self.rateBox = QLabel(str(self.rate) + 'x', self) self.rateBox.setAlignment(Qt.AlignCenter) self.hlightSliderTips = HlightSliderTipsWidget() self.positionSlider = QSlider(Qt.Horizontal) self.positionSlider.setRange(0, 0) def create_menu_bar(self): openAction = create_action('open.png', '&Open', 'Ctrl+O', 'Open video', self.openFile, self) saveAction = create_action('save.png', '&Save Clips', 'Ctrl+S', 'Save anonimized clips', self.saveClips, self) exitAction = create_action('exit.png', '&Exit', 'Ctrl+Q', 'Exit', self.exitCall, self) menuBar = self.menuBar() fileMenu = menuBar.addMenu('&File') fileMenu.addAction(openAction) fileMenu.addAction(saveAction) fileMenu.addAction(exitAction) def set_layout(self, videoWidget, wid): labellingLayout = QVBoxLayout() labellingLayout.addWidget(self.clipsWidget) controlLayout = self.make_control_layout() videoAreaLayout = QVBoxLayout() videoWidget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) videoAreaLayout.addWidget(videoWidget) videoAreaLayout.addLayout(controlLayout) videoAreaLayout.addWidget(self.errorLabel) layout = QHBoxLayout() layout.addLayout(videoAreaLayout, 4) layout.addLayout(labellingLayout) wid.setLayout(layout) def make_control_layout(self): buttonsLayout = QHBoxLayout() buttonsLayout.setContentsMargins(0, 0, 0, 0) buttonsLayout.addWidget(self.timeBox) buttonsLayout.addWidget(self.slowDownButton) buttonsLayout.addWidget(self.goBackButton) buttonsLayout.addWidget(self.goBack3Button) buttonsLayout.addWidget(self.playButton) buttonsLayout.addWidget(self.adv3Button) buttonsLayout.addWidget(self.advanceButton) buttonsLayout.addWidget(self.speedUpButton) buttonsLayout.addWidget(self.rateBox) cutLayout = QHBoxLayout() cutLayout.setContentsMargins(0, 0, 0, 0) cutLayout.addSpacerItem(QSpacerItem(200, 5, QSizePolicy.Minimum, QSizePolicy.Minimum)) cutLayout.addWidget(self.cutButton) cutLayout.addSpacerItem(QSpacerItem(200, 5, QSizePolicy.Minimum, QSizePolicy.Minimum)) layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self.positionSlider) layout.addWidget(self.hlightSliderTips) layout.addLayout(buttonsLayout) layout.addLayout(cutLayout) return layout def openFile(self): self.rawFileName, _ = QFileDialog.getOpenFileName(self, "Open video", QDir.homePath()) if self.rawFileName != '': should_process = QMessageBox.question(self.wid, 'Open video', 'Do you want to pre process the video?', QMessageBox.Yes | QMessageBox.No) if should_process == QMessageBox.Yes: self.fileName = TMP_VIDEO_PATH process = ProcVideoDialog(self.rawFileName, self.fileName, self) self.comm.videoProcessed.connect(self.openMedia) else: self.fileName = self.rawFileName self.processMetaData() self.openMedia() def processMetaData(self): ''' Get array indicating "suspicious" frames ''' # open metadata file self.metaDataFile = self.fileName.rsplit(".", 1)[0] + ".csv" # get only the array with "colors" (==0: green; !=0: red) self.colorsArray = get_metadata_colors(self.metaDataFile) self.hlightSliderTips.setColorsArray(self.colorsArray, useYellow=False) @pyqtSlot() def openMedia(self): self.mediaPlayer.setMedia( QMediaContent(QUrl.fromLocalFile(self.fileName))) self.openedFile = os.path.basename(self.fileName) self.setWindowTitle("sofa - " + self.openedFile) self.playButton.setEnabled(True) self.speedUpButton.setEnabled(True) self.slowDownButton.setEnabled(True) self.advanceButton.setEnabled(True) self.adv3Button.setEnabled(True) self.goBackButton.setEnabled(True) self.goBack3Button.setEnabled(True) self.cutButton.setEnabled(True) self.rate = 1 def exitCall(self): if self.openedFile is not None: os.remove(self.fileName) sys.exit(self.app.exec_()) def play(self): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.mediaPlayer.pause() else: self.mediaPlayer.play() def slow(self): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.rate -= 0.5 # TODO: Workaround pt 1 # https://forum.qt.io/topic/88490/change-playback-rate-at-... # ...runtime-problem-with-position-qmediaplayer/8 currentPos = self.mediaPlayer.position() # TODO: Workaround pt 1 self.mediaPlayer.setPlaybackRate(self.rate) # TODO: Workaround pt 2 self.mediaPlayer.setPosition(currentPos) # TODO: Workaround pt 2: end self.rateBox.setText(str(self.rate)+'x') def speed(self): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.rate += 0.5 # TODO: Workaround pt 1 # https://forum.qt.io/topic/88490/change-playback-rate-at-... # ...runtime-problem-with-position-qmediaplayer/8 currentPos = self.mediaPlayer.position() # TODO: Workaround pt 1 self.mediaPlayer.setPlaybackRate(self.rate) # TODO: Workaround pt 2 self.mediaPlayer.setPosition(currentPos) # TODO: Workaround pt 2: end self.rateBox.setText(str(self.rate)+'x') def advance(self, t=10): currentPos = self.mediaPlayer.position() nextPos = currentPos + t*1000 self.setPosition(nextPos) def back(self, t=10): currentPos = self.mediaPlayer.position() nextPos = max(currentPos - t*1000, 0) self.setPosition(nextPos) def mediaStateChanged(self, state): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.playButton.setIcon( self.style().standardIcon(QStyle.SP_MediaPause)) else: self.playButton.setIcon( self.style().standardIcon(QStyle.SP_MediaPlay)) def positionChanged(self, position): self.positionSlider.setValue(position) self.hlightSliderTips.setValue(position) self.timeBox.setText(format_time(int(position/1000))) def durationChanged(self, duration): self.positionSlider.setRange(0, duration) self.hlightSliderTips.setRange(duration) def setPosition(self, position): self.mediaPlayer.setPosition(position) def handleError(self): self.playButton.setEnabled(False) self.speedUpButton.setEnabled(False) self.slowDownButton.setEnabled(False) self.advanceButton.setEnabled(False) self.goBackButton.setEnabled(False) self.errorLabel.setText("Error: " + self.mediaPlayer.errorString()) def saveClips(self): prefix = os.path.splitext(os.path.basename(self.rawFileName))[0] + \ '_slice_' dirPath = QFileDialog.getExistingDirectory(self, 'Select Dir') if dirPath != '': try: self.errorLabel.setText('Saving clips... please wait') video = VideoFileClip(self.fileName) marks = self.clipsWidget.get_marks() begin_time = 0.0 for i, m in enumerate(marks): end_time = float(m[0]) out_path = os.path.join(dirPath, prefix+str(i)+".mp4") clip = video.subclip(begin_time, end_time) clip.write_videofile(out_path) begin_time = float(m[1]) end_video = self.mediaPlayer.duration()/1000 if begin_time < end_video and len(marks) > 0: i = len(marks) out_path = os.path.join(dirPath, prefix+str(i)+".mp4") clip = video.subclip(begin_time) clip.write_videofile(out_path) self.errorLabel.setText('Clips saved at ' + dirPath) QMessageBox.information(self.wid, 'Sucess', 'Clips succesfully saved') except: self.errorLabel.setText('Error: Could not save file.') QMessageBox.warning(self.wid, 'Error', 'Could not save file. Check permissions') @pyqtSlot() def createMark(self): state = self.mediaPlayer.state() if state == QMediaPlayer.PlayingState or state == \ QMediaPlayer.PausedState: self.clipsWidget.new_mark(self.mediaPlayer.position()/1000, self.isNewMark) self.isNewMark = not self.isNewMark
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 MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() uic.loadUi('mainwindow.ui', self) # Pre-setting self.FullScreenBt.setVisible(False) #region = QRegion(QRect(0,0,60,60), QRegion.Ellipse) self.PlayBt.setIcon(QIcon('./play.svg')) self.PlayBt.setIconSize(QSize(58, 58)) #self.PlayBt.setMask(region) self.PauseBt.setIcon(QIcon('./pause.svg')) self.PauseBt.setIconSize(QSize(58, 58)) #self.PauseBt.setMask(region) self.StopBt.setIcon(QIcon('./stop.svg')) self.StopBt.setIconSize(QSize(58, 58)) #self.StopBt.setMask(region) self.UploadBt.setIcon(QIcon('./download.svg')) self.UploadBt.setIconSize(QSize(58, 58)) #self.UploadBt.setMask(region) self.player = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.player.setVideoOutput(self.VideoScreen) self.slider.setValue(0) self.PlayBt.clicked.connect(self.Play) self.PauseBt.clicked.connect(self.Pause) self.StopBt.clicked.connect(self.Stop) self.UploadBt.clicked.connect(self.Upload) self.slider.sliderMoved.connect(self.setPosition) self.player.positionChanged.connect(self.setPositionOfSlider) self.FullScreenBt.clicked.connect(self.setFullscreen) self.PlayBt.setEnabled(False) self.PauseBt.setEnabled(False) self.StopBt.setEnabled(False) self.slider.setEnabled(False) self.FullScreenBt.setEnabled(False) def Play(self): if (self.player.position() == self.player.duration()): self.player.setPosition(0) self.slider.setValue(0) self.player.play() self.slider.setEnabled(True) self.PauseBt.setEnabled(True) self.StopBt.setEnabled(True) self.slider.setMaximum(self.player.duration()) def Pause(self): self.player.pause() self.PauseBt.setEnabled(False) def Stop(self): self.player.stop() self.player.play() self.player.pause() self.PauseBt.setEnabled(True) def Upload(self): file = QFileDialog() file, trash = file.getOpenFileUrls() if file: print(file) self.player.setMedia(QMediaContent(file[0])) self.PlayBt.setEnabled(True) #self.FullScreenBt.setEnabled(True) self.player.setPosition(0) self.slider.setValue(0) self.player.play() self.player.pause() def setPosition(self): self.player.setPosition(self.slider.value()) def setPositionOfSlider(self): self.slider.setValue(self.player.position()) def setFullscreen(self): self.VideoScreen.setFullScreen(True)
class MyMainWindow(QMainWindow, Ui_musicPlayer): def __init__(self, parent=None): super(MyMainWindow, self).__init__(parent) self.setupUi(self) self.player = QMediaPlayer() # --计时器 self.timer = QTimer(self) self.timer.start(1000) self.songs_list_select = [] self.song_formats = ['mp3', 'm4a', 'flac', 'wav', 'ogg'] self.settingfilename = 'setting.ini' self.cur_path = os.path.abspath(os.path.dirname(__file__)) self.cur_playing_song = '' self.is_switching = False self.is_pause = True self.openDir.clicked.connect(self.open_Dir) self.playStop.clicked.connect(self.playMusic) self.horizontalSlider.sliderMoved[int].connect( lambda: self.player.setPosition(self.horizontalSlider.value())) self.songUp.clicked.connect(self.previewMusic) self.songDn.clicked.connect(self.nextMusic) self.listWidget.doubleClicked.connect(self.doubleClicked) self.timer.timeout.connect(self.playByMode) def loadsetting(self): if os.path.isfile(self.settingfilename): config = configparser.ConfigParser() config.read(self.settingfilename) self.cur_path = config.get('MusicPlayer', 'PATH') self.showMusicList() def savesetting(self): config = configparser.ConfigParser() config.read(self.settingfilename) if not os.path.isfile(self.settingfilename): config.add_section('MusicPlayer') config.set('MusicPlayer', 'PATH', self.cur_path) config.write(open(self.settingfilename, 'w')) '''提示''' def Tips(self, message): QMessageBox.about(self, "提示", message) def open_Dir(self): self.cur_path = QFileDialog.getExistingDirectory( self, "选取文件夹", self.cur_path) if self.cur_path: self.showMusicList() self.cur_playing_song = '' self.setCurPlaying() self.label.setText('00:00') self.label_2.setText('00:00') self.horizontalSlider.setSliderPosition(0) self.is_pause = True self.playStop.setText('播放') def showMusicList(self): self.listWidget.clear() # self.updateSetting() for song in os.listdir(self.cur_path): if song.split('.')[-1] in self.song_formats: self.songs_list_select.append([ song, os.path.join(self.cur_path, song).replace('\\', '/') ]) self.listWidget.addItem(song) self.listWidget.setCurrentRow(0) if self.songs_list_select: self.cur_playing_song = self.songs_list_select[ self.listWidget.currentRow()][-1] '''根据播放模式播放音乐''' def playByMode(self): if (not self.is_pause) and (not self.is_switching): self.horizontalSlider.setMinimum(0) self.horizontalSlider.setMaximum(self.player.duration()) self.horizontalSlider.setValue(self.horizontalSlider.value() + 1000) self.label.setText( time.strftime('%M:%S', time.localtime(self.player.position() / 1000))) self.label_2.setText( time.strftime('%M:%S', time.localtime(self.player.duration() / 1000))) if (self.playType.currentIndex() == 0) and (not self.is_pause) and (not self.is_switching): if self.listWidget.count() == 0: return if self.player.position() == self.player.duration(): self.nextMusic() elif (self.playType.currentIndex() == 1) and (not self.is_pause) and (not self.is_switching): if self.listWidget.count() == 0: return if self.player.position() == self.player.duration(): self.is_switching = True self.setCurPlaying() self.horizontalSlider.setValue(0) self.playMusic() self.is_switching = False elif (self.playType.currentIndex() == 2) and (not self.is_pause) and (not self.is_switching): if self.listWidget.count() == 0: return if self.player.position() == self.player.duration(): self.is_switching = True self.listWidget.setCurrentRow( random.randint(0, self.qlist.count() - 1)) self.setCurPlaying() self.horizontalSlider.setValue(0) self.playMusic() self.is_switching = False '''双击播放音乐''' def doubleClicked(self): self.horizontalSlider.setValue(0) self.is_switching = True self.setCurPlaying() self.playMusic() self.is_switching = False '''设置当前播放的音乐''' def setCurPlaying(self): self.cur_playing_song = self.songs_list_select[ self.listWidget.currentRow()][-1] self.player.setMedia(QMediaContent(QUrl(self.cur_playing_song))) '''播放音乐''' def playMusic(self): if self.listWidget.count() == 0: self.Tips('当前路径内无可播放的音乐文件') return if not self.player.isAudioAvailable(): self.setCurPlaying() if self.is_switching or self.is_pause: self.player.play() self.is_pause = False self.playStop.setText('暂停') elif (not self.is_pause) and (not self.is_switching): self.player.pause() self.is_pause = True self.playStop.setText('播放') '''上一首''' def previewMusic(self): self.horizontalSlider.setValue(0) if self.listWidget.count() == 0: self.Tips('当前路径内无可播放的音乐文件') return pre_row = self.listWidget.currentRow( ) - 1 if self.listWidget.currentRow( ) != 0 else self.listWidget.count() - 1 self.listWidget.setCurrentRow(pre_row) self.is_switching = True self.setCurPlaying() self.playMusic() self.is_switching = False '''下一首''' def nextMusic(self): self.horizontalSlider.setValue(0) if self.listWidget.count() == 0: self.Tips('当前路径内无可播放的音乐文件') return next_row = self.listWidget.currentRow( ) + 1 if self.listWidget.currentRow( ) != self.listWidget.count() - 1 else 0 self.listWidget.setCurrentRow(next_row) self.is_switching = True self.setCurPlaying() self.playMusic() self.is_switching = False
class Player(QWidget): audio_path = "audio" lyrics_path = "lyrics" timings_path = os.path.join("lyrics", "timing") settings_path = "settings.json" fullScreenChanged = pyqtSignal(bool) def __init__(self, parent=None): super(Player, self).__init__(parent) self.setWindowTitle("SongScreen") self.setFocusPolicy(Qt.StrongFocus) self.colorDialog = None self.trackInfo = "" self.statusInfo = "" self.duration = 0 self.player = QMediaPlayer() self.playlist = QMediaPlaylist() self.player.setPlaylist(self.playlist) self.player.durationChanged.connect(self.durationChanged) self.player.positionChanged.connect(self.positionChanged) self.player.metaDataChanged.connect(self.metaDataChanged) # self.playlist.currentIndexChanged.connect(self.playlistPositionChanged) self.player.mediaStatusChanged.connect(self.statusChanged) self.player.bufferStatusChanged.connect(self.bufferingProgress) self.player.videoAvailableChanged.connect(self.videoAvailableChanged) self.player.error.connect(self.displayErrorMessage) # self.videoWidget = VideoWidget() # self.player.setVideoOutput(self.videoWidget) self.slider = MediaProgressWidget() # QSlider(Qt.Horizontal) self.markers = [] self.songtext_widget = SongTextWidget() self.songtext_widget.show() # self.playlistModel = PlaylistModel() # self.playlistModel.setPlaylist(self.playlist) # # self.playlistView = QListView() # self.playlistView.setModel(self.playlistModel) # self.playlistView.setCurrentIndex( # self.playlistModel.index(self.playlist.currentIndex(), 0)) # # self.playlistView.activated.connect(self.jump) self.slider.setRange(0, self.player.duration() / 1000) self.labelDuration = QLabel() self.slider.sliderMoved.connect(self.seek) # openButton = QPushButton("Open", clicked=self.open) controls = PlayerControlsWidget() controls.setState(self.player.state()) controls.setVolume(self.player.volume()) # controls.setMuted(controls.isMuted()) controls.play.connect(self.player.play) controls.pause.connect(self.player.pause) controls.stop.connect(self.stop_clicked) # controls.stop.connect(self.videoWidget.update) # controls.next.connect(self.playlist.next) # controls.previous.connect(self.previousClicked) controls.changeVolume.connect(self.player.setVolume) # controls.changeMuting.connect(self.player.setMuted) # controls.changeRate.connect(self.player.setPlaybackRate) self.player.stateChanged.connect(controls.setState) self.player.stateChanged.connect(self.setState) self.player.volumeChanged.connect(controls.setVolume) # self.player.mutedChanged.connect(controls.setMuted) # self.fullScreenButton = QPushButton("FullScreen") # self.fullScreenButton.setCheckable(True) # # self.colorButton = QPushButton("Color Options...") # self.colorButton.setEnabled(False) # self.colorButton.clicked.connect(self.showColorDialog) displayLayout = QHBoxLayout() # displayLayout.addWidget(self.videoWidget, 2) # displayLayout.addWidget(self.songtext_widget) # displayLayout.addWidget(self.playlistView) self.song_select_widget = SongSelectWidget() self.song_select_widget.song_selected.connect(self.load_song) self.screen_select_widget = ScreenSelectWidget() self.screen_select_widget.screen_selected.connect(self.display_lyrics_on_screen) self.screen_select_widget.active_screen = QApplication.desktop().screenNumber(self.songtext_widget) self.settings_button = QPushButton() self.settings_button.setText(self.tr("Settings...")) self.settings_button.clicked.connect(self.show_settings) sidebarLayout = QVBoxLayout() sidebarLayout.setContentsMargins(10, 1, 0, 1); sidebarLayout.addWidget(self.settings_button) sidebarLayout.addStretch(1); sidebarLayout.addWidget(self.screen_select_widget) displayLayout.addWidget(self.song_select_widget) displayLayout.addLayout(sidebarLayout) controlLayout = QHBoxLayout() controlLayout.setContentsMargins(0, 0, 0, 0) # controlLayout.addWidget(openButton) # controlLayout.addStretch(1) controlLayout.addWidget(controls) controlLayout.addStretch(1) controlLayout.addWidget(self.labelDuration) # controlLayout.addWidget(self.fullScreenButton) # controlLayout.addWidget(self.colorButton) layout = QVBoxLayout() layout.addLayout(displayLayout) hLayout = QHBoxLayout() hLayout.addWidget(self.slider) # hLayout.addWidget(self.labelDuration) layout.addLayout(hLayout) layout.addLayout(controlLayout) self.setLayout(layout) if not self.player.isAvailable(): QMessageBox.warning(self, "Service not available", "The QMediaPlayer object does not have a valid service.\n" "Please check the media service plugins are installed.") controls.setEnabled(False) self.playlistView.setEnabled(False) # openButton.setEnabled(False) self.colorButton.setEnabled(False) self.fullScreenButton.setEnabled(False) self.metaDataChanged() self._loading_audio = False self._finished_song = False self._lyrics_fading = False self._song_number = -1 self.settings = { 'font_size': 40, 'line_increment': 2, 'lyrics_language': '', } self._load_settings() self.settings_widget = SettingsWidget(self.settings, self.lyrics_path) self.settings_widget.font_size_changed.connect(self.songtext_widget.set_font_size) self.settings_widget.line_increment_changed.connect(self.songtext_widget.set_line_increment) self.settings_widget.language_changed.connect(self._language_changed) self.song_select_widget.reset(self.available_song_numbers) @property def lyrics_language_path(self): path = QStandardPaths.locate(QStandardPaths.AppDataLocation, self.lyrics_path, QStandardPaths.LocateDirectory) return os.path.join(path, self.settings['lyrics_language']) @property def available_song_numbers(self): audios = set( [int(os.path.splitext(filename)[0]) for filename in os.listdir(self.audio_path) if filename[0] != '.']) try: lyrics = set( [int(os.path.splitext(filename)[0]) for filename in os.listdir(self.lyrics_language_path) if filename[0] != '.'] ) except (ValueError, FileNotFoundError): lyrics = set() return sorted(list(audios.intersection(lyrics))) def show_settings(self): self.settings_widget.hide() self.settings_widget.show() def display_lyrics_on_screen(self, screen_number): desktop = QApplication.desktop() if screen_number >= desktop.screenCount(): screen_number = desktop.screenNumber(self) rect = desktop.availableGeometry(screen_number) for _ in range(3): if screen_number != desktop.screenNumber(self): self.songtext_widget.setWindowFlags(Qt.FramelessWindowHint) self.songtext_widget.hide() self.songtext_widget.move(rect.x(), rect.y()) self.songtext_widget.resize(rect.width(), rect.height()) self.songtext_widget.showFullScreen() else: self.songtext_widget.setWindowFlags(Qt.WindowTitleHint) self.songtext_widget.hide() self.songtext_widget.move(rect.x(), rect.y()) self.songtext_widget.resize(self.songtext_widget.minimumSize()) self.songtext_widget.show() self.screen_select_widget.active_screen = screen_number self.activateWindow() def load_song(self, song_number): if self._song_number == song_number: self.seek(0) else: if self._song_number > 0: self._save_timings() self._song_number = song_number self.slider.dirty = False self._load_audio() self._load_lyrics() # self.player.play() def _load_audio(self): filename = os.path.join(self.audio_path, "{:03}.mp3".format(self._song_number)) self.playlist.clear() fileInfo = QFileInfo(filename) if fileInfo.exists(): url = QUrl.fromLocalFile(fileInfo.absoluteFilePath()) if fileInfo.suffix().lower() == 'm3u': self.playlist.load(url) else: self.playlist.addMedia(QMediaContent(url)) self._loading_audio = True self.player.play() def _load_lyrics(self): with open(os.path.join(self.lyrics_language_path, "{}.json".format(self._song_number)), 'r') as f: song_markers = json.load(f) self.markers = [] for m in song_markers['markers']: marker = MediaMarker(self.slider, m['name']) marker.text = m['text'] marker.progress = 0.0 self.markers.append(marker) self.songtext_widget.title = "{} {}".format(self._song_number, song_markers['title']) self.songtext_widget.markers = self.markers self.songtext_widget.fade_in() try: with open(os.path.join(self.timings_path, "{}.json".format(self._song_number)), 'r') as f: timings = json.load(f) for m, t in zip(self.markers, timings): m.progress = t except FileNotFoundError: pass self.slider.markers = self.markers def _language_changed(self, _): available_song_numbers = self.available_song_numbers self.song_select_widget.reset(available_song_numbers) if self._song_number in available_song_numbers: self._load_lyrics() # def open(self): # fileNames, _ = QFileDialog.getOpenFileNames(self, "Open Files") # self.addToPlaylist(fileNames) # # def addToPlaylist(self, fileNames): # for name in fileNames: # fileInfo = QFileInfo(name) # if fileInfo.exists(): # url = QUrl.fromLocalFile(fileInfo.absoluteFilePath()) # if fileInfo.suffix().lower() == 'm3u': # self.playlist.load(url) # else: # self.playlist.addMedia(QMediaContent(url)) # else: # url = QUrl(name) # if url.isValid(): # self.playlist.addMedia(QMediaContent(url)) def durationChanged(self, duration): duration /= 1000 self.duration = duration self.slider.setMaximum(duration) if self._loading_audio: self._loading_audio = False line_total = 0 for marker in self.markers: line_total += marker.linecount - 1 silence_ratio = 5.0 / self.duration offset = 1.8 / line_total linecount = 0 for marker in self.markers: if marker.progress == 0.0: marker.progress = offset + (1 - offset) * (1 - silence_ratio) * linecount / line_total linecount += marker.linecount - 1 self.player.pause() @property def _should_fade_out(self): return self.player.position() / 1000 >= self.duration - 5 def positionChanged(self, progress): progress /= 1000 if not self.slider.isSliderDown(): self.slider.setValue(progress) self.updateDurationInfo(progress) if self.duration > 0: # if self.player.state() == QMediaPlayer.PlayingState: self.songtext_widget.progress = progress / self.duration if self._should_fade_out: self._fade_out_lyrics() def _fade_out_lyrics(self): if not self._lyrics_fading: self._lyrics_fading = True self.songtext_widget.fade_out() def metaDataChanged(self): if self.player.isMetaDataAvailable(): self.setTrackInfo("%s - %s" % ( self.player.metaData(QMediaMetaData.AlbumArtist), self.player.metaData(QMediaMetaData.Title))) def previousClicked(self): # Go to the previous track if we are within the first 5 seconds of # playback. Otherwise, seek to the beginning. if self.player.position() <= 5000: self.playlist.previous() else: self.player.setPosition(0) def jump(self, index): if index.isValid(): self.playlist.setCurrentIndex(index.row()) self.player.play() def seek(self, seconds): self.player.setPosition(seconds * 1000) def setState(self, status): if status == QMediaPlayer.StoppedState: self._finished_song = True elif status == QMediaPlayer.PlayingState: if self._finished_song or (self._lyrics_fading and not self._should_fade_out): self._finished_song = False self._lyrics_fading = False self.songtext_widget.fade_in() def stop_clicked(self): self.player.stop() self._fade_out_lyrics() def statusChanged(self, status): self.handleCursor(status) if status == QMediaPlayer.LoadingMedia: self.setStatusInfo("Loading...") elif status == QMediaPlayer.StalledMedia: self.setStatusInfo("Media Stalled") elif status == QMediaPlayer.EndOfMedia: QApplication.alert(self) elif status == QMediaPlayer.InvalidMedia: self.displayErrorMessage() else: self.setStatusInfo("") def handleCursor(self, status): if status in (QMediaPlayer.LoadingMedia, QMediaPlayer.BufferingMedia, QMediaPlayer.StalledMedia): self.setCursor(Qt.BusyCursor) else: self.unsetCursor() def bufferingProgress(self, progress): self.setStatusInfo("Buffering %d%" % progress) def videoAvailableChanged(self, available): if available: self.fullScreenButton.clicked.connect( self.videoWidget.setFullScreen) self.videoWidget.fullScreenChanged.connect( self.fullScreenButton.setChecked) if self.fullScreenButton.isChecked(): self.videoWidget.setFullScreen(True) else: self.fullScreenButton.clicked.disconnect( self.videoWidget.setFullScreen) self.videoWidget.fullScreenChanged.disconnect( self.fullScreenButton.setChecked) self.videoWidget.setFullScreen(False) self.colorButton.setEnabled(available) def setTrackInfo(self, info): self.trackInfo = info # if self.statusInfo != "": # self.setWindowTitle("%s | %s" % (self.trackInfo, self.statusInfo)) # else: # self.setWindowTitle(self.trackInfo) def setStatusInfo(self, info): self.statusInfo = info # if self.statusInfo != "": # self.setWindowTitle("%s | %s" % (self.trackInfo, self.statusInfo)) # else: # self.setWindowTitle(self.trackInfo) def displayErrorMessage(self): self.setStatusInfo(self.player.errorString()) def updateDurationInfo(self, currentInfo): duration = self.duration if currentInfo or duration: currentTime = QTime((currentInfo / 3600) % 60, (currentInfo / 60) % 60, currentInfo % 60, (currentInfo * 1000) % 1000) totalTime = QTime((duration / 3600) % 60, (duration / 60) % 60, duration % 60, (duration * 1000) % 1000); format = 'hh:mm:ss' if duration > 3600 else 'mm:ss' tStr = currentTime.toString(format) + " / " + totalTime.toString(format) else: tStr = "" self.labelDuration.setText(tStr) def showColorDialog(self): if self.colorDialog is None: brightnessSlider = QSlider(Qt.Horizontal) brightnessSlider.setRange(-100, 100) brightnessSlider.setValue(self.videoWidget.brightness()) brightnessSlider.sliderMoved.connect( self.videoWidget.setBrightness) self.videoWidget.brightnessChanged.connect( brightnessSlider.setValue) contrastSlider = QSlider(Qt.Horizontal) contrastSlider.setRange(-100, 100) contrastSlider.setValue(self.videoWidget.contrast()) contrastSlider.sliderMoved.connect(self.videoWidget.setContrast) self.videoWidget.contrastChanged.connect(contrastSlider.setValue) hueSlider = QSlider(Qt.Horizontal) hueSlider.setRange(-100, 100) hueSlider.setValue(self.videoWidget.hue()) hueSlider.sliderMoved.connect(self.videoWidget.setHue) self.videoWidget.hueChanged.connect(hueSlider.setValue) saturationSlider = QSlider(Qt.Horizontal) saturationSlider.setRange(-100, 100) saturationSlider.setValue(self.videoWidget.saturation()) saturationSlider.sliderMoved.connect( self.videoWidget.setSaturation) self.videoWidget.saturationChanged.connect( saturationSlider.setValue) layout = QFormLayout() layout.addRow("Brightness", brightnessSlider) layout.addRow("Contrast", contrastSlider) layout.addRow("Hue", hueSlider) layout.addRow("Saturation", saturationSlider) button = QPushButton("Close") layout.addRow(button) self.colorDialog = QDialog(self) self.colorDialog.setWindowTitle("Color Options") self.colorDialog.setLayout(layout) button.clicked.connect(self.colorDialog.close) self.colorDialog.show() def closeEvent(self, close_event): self._save_timings() self._save_settings() self.songtext_widget.close() self.settings_widget.close() def keyPressEvent(self, key_event): if key_event.key() == Qt.Key_Space: key_event.accept() if self.player.state() == QMediaPlayer.PlayingState: self.player.pause() elif self.player.state() in [QMediaPlayer.PausedState, QMediaPlayer.StoppedState]: self.player.play() elif key_event.key() == Qt.Key_M: key_event.accept() self.slider.set_closest_marker_to_current_progress() def _save_timings(self): if self.slider.dirty: with open(os.path.join(self.timings_path, "{}.json".format(self._song_number)), 'w') as f: json.dump([marker.progress for marker in self.markers], f, indent=2) def _save_settings(self): # TODO : refactor and use QSettings directly # with open(self.settings_path, 'w') as f: self.settings.update({ 'lyrics_screen': QApplication.desktop().screenNumber(self.songtext_widget), 'control_window_position': self.pos(), }) # json.dump(self.settings, f, indent=2) settings = QSettings("Maccesch", "SongScreen") for key, value in self.settings.items(): settings.setValue(key, value) def _load_settings(self): # try: # with open(self.settings_path, 'r') as f: # settings = json.load(f) settings = QSettings("Maccesch", "SongScreen") if settings.contains('lyrics_screen'): self.display_lyrics_on_screen(settings.value('lyrics_screen')) if settings.contains('control_window_position'): self.move(settings.value('control_window_position')) for key in settings.allKeys(): self.settings[key] = settings.value(key) # self.settings.update(settings) self.songtext_widget.set_font_size(self.settings['font_size']) self.songtext_widget.set_line_increment(self.settings['line_increment']) # except (FileNotFoundError, ValueError): # pass if not os.path.exists(self.lyrics_language_path) or not self.settings['lyrics_language']: languages = list( filter(lambda p: os.path.isdir(os.path.join(self.lyrics_path, p)) and p != "timings", os.listdir(self.lyrics_path)) ) self.settings['lyrics_language'] = languages[0] if languages else ""
class AudioPlayer(QObject): songPositionChanged = pyqtSignal(int) songDurationChanged = pyqtSignal(int) stateChanged = pyqtSignal(int) playlistChanged = pyqtSignal(QMediaPlaylist, int) currentSongChanged = pyqtSignal(str, str, bytes) currentSelectionChanged = pyqtSignal(UUID, int) customPlaylistCreated = pyqtSignal(UUID, str) libraryPlaylistCreated = pyqtSignal(UUID) addedToLibraryPlaylist = pyqtSignal(UUID, list) addedToCustomPlaylist = pyqtSignal(UUID, list) updatedLibraryPlaylist = pyqtSignal(UUID, list) playlistRemoved = pyqtSignal(UUID) def __init__(self, volumeLevel=40, playbackMode=QMediaPlaylist.Sequential, parent=None): super(AudioPlayer, self).__init__(parent) self.__player = QMediaPlayer() self.__player.setVolume(volumeLevel) self.__player.currentMediaChanged.connect(self._onMediaChanged) self.__player.stateChanged.connect( lambda state: self.stateChanged.emit(int(state))) self.__player.positionChanged.connect( lambda x: self.songPositionChanged.emit(x)) self.__player.durationChanged.connect( lambda x: self.songDurationChanged.emit(x)) self.__playlistManager = PlaylistManger() self.__playlistManager.customPlaylistCreated.connect( lambda uuid, name: self.customPlaylistCreated.emit(uuid, name)) self.__playlistManager.libraryPlaylistCreated.connect( lambda p: self.libraryPlaylistCreated.emit(p)) self.__playlistManager.currentPlaylistChanged.connect( self._onChangedPlaylist) self.__playlistManager.currentPlaylistChanged.connect( lambda p, i: self.playlistChanged.emit(p, i)) self.__playlistManager.playlistRemoved.connect( lambda uuid: self.playlistRemoved.emit(uuid)) self.__playlistManager.addedToLibraryPlaylist.connect( lambda uuid, l: self.addedToLibraryPlaylist.emit(uuid, l)) self.__playlistManager.addedToCustomPlaylist.connect( lambda uuid, l: self.addedToCustomPlaylist.emit(uuid, l)) self.__playlistManager.updatedLibraryPlaylist.connect( lambda uuid, l: self.updatedLibraryPlaylist.emit(uuid, l)) def createCustomPlaylist(self, name=None, urls=None): self.__playlistManager.createCustomPlaylist(name, urls) def createLibraryPlaylist(self, urls=None): self.__playlistManager.createLibraryPlaylist(urls) def addToLibraryPlaylist(self, url=None): self.__playlistManager.addToLibraryPlaylist(url) def updateLibraryPlaylist(self, url=None): self.__playlistManager.updateLibraryPlaylist(url) def renamePlaylist(self, uuid, newName): self.__playlistManager.renamePlaylist(uuid, newName) def addSongsToCustomPlaylist(self, uuid, urls=[]): self.__playlistManager.addSongsToCustomPlaylist(uuid, urls) def removeSong(self, uuid, row): self.__playlistManager.removeSong(uuid, row) def setPlaylist(self, uuid, index=0): if (self.__player.playlist() and self.__playlistManager.isCurrentPlaylist(uuid)): if index == self.__player.playlist().currentIndex(): if self.__player.state() == QMediaPlayer.PlayingState: self.__player.pause() else: self.__player.play() else: self.__player.playlist().setCurrentIndex(index) else: self.__playlistManager.setPlaylist(uuid, index) def hasLibraryPlaylist(self): return self.__playlistManager.hasLibraryPlaylist() def removePlaylist(self, uuid): self.__playlistManager.removePlaylist(uuid) def getCurrentPlaylist(self): self.__playlistManager.getCurrentPlaylist() def getCurrentQMediaPlaylist(self): self.__player.playlist() def isPlayerAvailable(self): return self.__player.isAvailable() def getDuration(self): return self.__player.duration() def getPlayer(self): return self.__player def getState(self): return self.__player.state() def play(self): if self.__player.playlist(): self.__player.play() def pause(self): if self.__player.playlist(): self.__player.pause() def stop(self): if self.__player.playlist(): self.__player.stop() def previousEnhanced(self, sameSongMillis): if self.__player.position() <= sameSongMillis: self.previous() else: self.__player.setPosition(0) def previous(self): if self.__player.playlist(): self.__player.playlist().previous() def next(self): if self.__player.playlist(): self.__player.playlist().next() def setVolume(self, value): self.__player.setVolume(value) def setPosition(self, milliseconds): self.__player.setPosition(milliseconds) def playlistCurrentIndex(self): if self.__player.playlist(): return self.__player.playlist().currentIndex() def setCurrentPlaylistIndex(self, index): if self.__player.playlist(): self.__player.playlist().setCurrentIndex(index) def _onChangedPlaylist(self, playlist, index, playIt=False): self.__player.setPlaylist(playlist) if playlist: playlist.setCurrentIndex(index) if playIt: self.play() def _onMediaChanged(self, media): if media.isNull() and self.__player.playlist(): self.__player.playlist().setCurrentIndex(0) media = self.__player.playlist().media(0) if media.isNull(): return title, artist, cover = self.__playlistManager.getBasicSongInfo(media) self.currentSongChanged.emit(title, artist, cover) uuid = self.__playlistManager.getCurrentPlaylistUuid() index = self.__playlistManager.getCurrentSongIndex() self.currentSelectionChanged.emit(uuid, index) # def saveSettings(self): # # settings = QSettings(QSettings.IniFormat, QSettings.UserScope, # # QCoreApplication.organizationName(), # # QCoreApplication.applicationName()) # # settings.beginGroup("music_player") # # # if self.__playlistManager.getLibraryPlaylist(): # # # libraryDirectories = self.__playlistManager.getLibraryPlaylist().getDirectories() # # # settings.beginWriteArray('library_playlist', # # # len(libraryDirectories)) # # # for index, value in enumerate(libraryDirectories): # # # settings.setArrayIndex(index) # # # settings.setValue("url", value) # # # settings.endArray() # # customPlaylists = self.__playlistManager.getCustomPlaylists() # # settings.beginWriteArray('custom_playlists', # # len(customPlaylists)) # # for index, value in enumerate(customPlaylists): # # settings.setArrayIndex(index) # # playlistName = settings.value('name', value.getName()) # # playlistUrls = value.getAddedSongUrls() # # settings.beginWriteArray(playlistName, # # len(playlistUrls)) # # for i, v in enumerate(playlistUrls): # # settings.setArrayIndex(i) # # settings.setValue("url", v) # # settings.endArray() # # settings.endArray() # # settings.endGroup() # # if self.__playlistManager.getLibraryPlaylist(): # # libraryDirectories = self.__playlistManager.getLibraryPlaylist().getDirectories() # # settings.beginWriteArray('library_playlist', # # len(libraryDirectories)) # # for index, value in enumerate(libraryDirectories): # # settings.setArrayIndex(index) # # settings.setValue("url", value) # # settings.endArray() # customPlaylists = self.__playlistManager.getCustomPlaylists() # for playlist in customPlaylists: # playlistName = playlist.getName() # for url in playlist: # pass # def restoreSettings(self): # settings = QSettings(QSettings.IniFormat, QSettings.UserScope, # QCoreApplication.organizationName(), # QCoreApplication.applicationName()) # settings.beginGroup("music_player") # # size = settings.beginReadArray('library_playlist') # # libraryDirectories = [] # # for i in range(size): # # settings.setArrayIndex(i) # # libraryDirectories.append(settings.value("url")) # # settings.endArray() # customPlaylists = {} # size = settings.beginReadArray('custom_playlists') # for i in range(size): # urls = [] # settings.setArrayIndex(i) # playlistName = settings.value('name') # print(playlistName) # size2 = settings.beginReadArray(playlistName) # for j in range(size2): # settings.setArrayIndex(j) # url = settings.value("url") # urls.append(url) # settings.endArray() # customPlaylists[playlistName] = urls # settings.endArray() # settings.endGroup() # print('-------') # print(customPlaylists) # settings = QSettings(QCoreApplication.organizationName(), # QCoreApplication.applicationName()) # settings.beginGroup("music_player") # size = settings.beginReadArray('library_playlist') # if not size == 0: # for i in range(0, size): # settings.setArrayIndex(i) # url = settings.value("url") # settings.endArray() # if url: # from audio.playlist_models import DirectoryPlaylist # playlist = DirectoryPlaylist() # playlist.add_directory(url) # self.addAndSetPlaylist(playlist, 2) # settings.endGroup() pass
class 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 Player(Qt.QWidget): """docstring for Player""" fullScreenChanged = Qt.pyqtSignal(bool) def __init__(self, playlist, parent=None): # create player super(Player, self).__init__(parent) self.trackInfo = '' self.statusInfo = '' self.duration = 0 # create player object self.player = QMediaPlayer() self.playlist = QMediaPlaylist() self.name = 'Current playlist' self.player.setPlaylist(self.playlist) self.player.durationChanged.connect(self.durationChanged) self.player.positionChanged.connect(self.positionChanged) self.player.metaDataChanged.connect(self.metaDataChanged) self.playlist.currentIndexChanged.connect(self.playlistPositionChanged) self.player.mediaStatusChanged.connect(self.statusChanged) self.player.bufferStatusChanged.connect(self.bufferingProgress) # self.player.videoAvailableChanged.connect(self.videoAvailableChanged) self.player.error.connect(self.displayErrorMessage) # connect with VideoWidget # self.videoWidget = VideoWidget() # self.player.setVideoOutput(self.videoWidget) # connect with PlaylistModel self.playlistModel = PlaylistModel() self.playlistModel.setPlaylist(self.playlist) self.playlistView = Qt.QListView() self.playlistView.setModel(self.playlistModel) self.playlistView.setCurrentIndex(self.playlistModel.index( self.playlist.currentIndex(), 0)) # change to next song self.playlistView.activated.connect(self.jump) self.slider = Qt.QSlider(QtCore.Qt.Horizontal) self.slider.setRange(0, self.player.duration() / 1000) self.labelDuration = Qt.QLabel() self.slider.sliderMoved.connect(self.seek) # create histogram self.labelHistogram = Qt.QLabel() self.labelHistogram.setText('Histogram: ') self.histogram = HistogramWidget() histogramLayout = Qt.QHBoxLayout() histogramLayout.addWidget(self.labelHistogram) histogramLayout.addWidget(self.histogram, 1) # create videoProbe self.videoProbe = Qt.QVideoProbe() self.videoProbe.videoFrameProbed.connect(self.histogram.processFrame) self.videoProbe.setSource(self.player) # add control controls = Controllers() controls.setState(self.player.state()) controls.setVolume(self.player.volume()) controls.setMuted(controls.isMuted()) # connect player's controls with Controllers controls.play.connect(self.player.play) controls.pause.connect(self.player.pause) controls.stop.connect(self.player.stop) controls.next.connect(self.playlist.next) controls.previous.connect(self.previousAction) controls.changeVolume.connect(self.player.setVolume) controls.changeMuting.connect(self.player.setMuted) # setPlaybackRate is from QMediaPlayer controls.changeSpeed.connect(self.player.setPlaybackRate) # controls.stop.connect(self.videoWidget.update) self.player.stateChanged.connect(controls.setState) self.player.volumeChanged.connect(controls.setVolume) self.player.mutedChanged.connect(controls.setMuted) # create fullScreenButton # self.fullScreenButton = Qt.QPushButton('FullScreen') # self.fullScreenButton.setCheckable(True) # displayLayout displayLayout = Qt.QHBoxLayout() # displayLayout.addWidget(self.videoWidget, 2) displayLayout.addWidget(self.playlistView) # controlLayout controlLayout = Qt.QHBoxLayout() controlLayout.setContentsMargins(0, 0, 0, 0) # connect controlLayout with controls controlLayout.addWidget(controls) controlLayout.addStretch(1) # connect controlLayout with fullScreenButton # controlLayout.addWidget(self.fullScreenButton) # visualize player layout = Qt.QVBoxLayout() layout.addLayout(displayLayout) # layout for sliding song playing hLayout = Qt.QHBoxLayout() hLayout.addWidget(self.slider) hLayout.addWidget(self.labelDuration) layout.addLayout(hLayout) layout.addLayout(controlLayout) layout.addLayout(histogramLayout) # set icon self.setWindowIcon(Qt.QIcon('favicon.ico')) # create menus toolBar = Qt.QToolBar() # create basic actions self.createActions() # create simple button to repeat song self.repeatButton = Qt.QToolButton() self.repeatButton.setDefaultAction(self.repeatAct) # create playOnceButton self.playOnceButton = Qt.QToolButton() self.playOnceButton.setDefaultAction(self.playOnceAct) self.playOnceButton.setEnabled(False) # create shuffleButton self.shuffleButton = Qt.QToolButton() self.shuffleButton.setDefaultAction(self.shuffleAct) # create sequentialButton self.sequentialButton = Qt.QToolButton() self.sequentialButton.setDefaultAction(self.sequentialAct) # create fileButton for fileMenu fileButton = Qt.QToolButton() fileButton.setText('File') fileButton.setPopupMode(Qt.QToolButton.MenuButtonPopup) fileButton.setMenu(self.popFileMenu()) # create editButton for editMenu closeButton = Qt.QToolButton() closeButton.setText('Edit') closeButton.setDefaultAction(self.fileCloseAct) # display in toolBar these buttons toolBar.addWidget(self.repeatButton) toolBar.addWidget(self.playOnceButton) toolBar.addWidget(self.shuffleButton) toolBar.addWidget(self.sequentialButton) toolBar.addWidget(fileButton) toolBar.addWidget(closeButton) # add toolBar to layout of the player layout.addWidget(toolBar) layout.addWidget(Qt.QGroupBox()) self.setWindowTitle("Python Music Player") self.setLayout(layout) if not self.player.isAvailable(): Qt.QMessageBox(self, 'Unavailable service') # self.displayErrorMessage() controls.setEnabled(False) self.playlistView.setEnabled(False) self.fullScreenButton.setEnabled(False) self.metaDataChanged() self.addToPlaylist(playlist) # create fileMenu def popFileMenu(self): aMenu = Qt.QMenu(self) aMenu.addAction(self.fileOpenAct) aMenu.addAction(self.fileCloseAct) return aMenu def createActions(self): self.repeatAct = Qt.QAction('Repeat', self, triggered=self.repeatSong) self.playOnceAct = Qt.QAction( 'Play once', self, triggered=self.playOnceSong) self.shuffleAct = Qt.QAction( 'Shuffle', self, triggered=self.playlist.shuffle) self.sequentialAct = Qt.QAction( 'Sequential', self, triggered=self.playSequential) self.fileOpenAct = Qt.QAction('Open', self, triggered=self.open) self.fileOpenAct.setShortcut('Ctrl+O') self.fileCloseAct = Qt.QAction('Close', self, triggered=self.close) self.fileCloseAct.setShortcut('Ctrl+Q') def repeatSong(self): self.playlist.setPlaybackMode(QMediaPlaylist.CurrentItemInLoop) self.repeatButton.setEnabled(False) self.playOnceButton.setEnabled(True) def playOnceSong(self): self.playlist.setPlaybackMode(QMediaPlaylist.Sequential) self.playOnceButton.setEnabled(False) self.repeatButton.setEnabled(True) # unproperly used def playSequential(self): self.playlist.setPlaybackMode(QMediaPlaylist.Sequential) # get and display song duration def durationChanged(self, duration): duration /= 1000 self.duration = duration self.slider.setMaximum(duration) # change slider position def positionChanged(self, progress): progress /= 1000 if not self.slider.isSliderDown(): self.slider.setValue(progress) self.updateDurationInfo(progress) def updateDurationInfo(self, currentInfo): duration = self.duration if currentInfo or duration: currentTime = QtCore.QTime( (currentInfo / 3600) % 60, # hours (currentInfo / 60) % 60, # minutes currentInfo % 60, # seconds (currentInfo * 1000) % 1000) # miliseconds totalTime = QtCore.QTime( (duration / 3600) % 60, # hours (duration / 60) % 60, # minutes duration % 60, # seconds (duration * 1000) % 1000) # miliseconds formating = 'hh:mm:ss' if duration > 3600 else 'mm:ss' toString = (currentTime.toString(formating) + ' / ' + totalTime.toString(formating)) else: toString = '' self.labelDuration.setText(toString) def metaDataChanged(self): if self.player.isMetaDataAvailable(): self.setTrackInfo('{0} - {1}'.format( self.player.metaData(Qt.QMediaMetaData.AlbumArtist), self.player.metaData(Qt.QMediaMetaData.Title))) def setTrackInfo(self, info): self.trackInfo = info if self.statusInfo: self.setWindowTitle('{0} | {1}'.format( self.trackInfo, self.statusInfo)) else: self.setWindowTitle(self.trackInfo) def playlistPositionChanged(self, position): self.playlistView.setCurrentIndex( self.playlistModel.index(position, 0)) def statusChanged(self, status): self.handleCursor(status) if status == QMediaPlayer.LoadingMedia: self.setStatusInfo('Loading...') elif status == QMediaPlayer.StalledMedia: self.setStatusInfo('Media Stalled') elif status == QMediaPlayer.EndOfMedia: Qt.QApplication.alert(self) elif status == QMediaPlayer.InvalidMedia: self.displayErrorMessage() else: self.setStatusInfo('') def handleCursor(self, status): if status in [QMediaPlayer.LoadingMedia, QMediaPlayer.BufferingMedia, QMediaPlayer.StalledMedia]: self.setCursor(QtCore.Qt.BusyCursor) else: self.unsetCursor() def setStatusInfo(self, info): self.statusInfo = info if self.statusInfo: self.setWindowTitle('{0} | {1}'.format( self.trackInfo, self.statusInfo)) else: self.setWindowTitle(self.trackInfo) def bufferingProgress(self, progress): self.setStatusInfo('Buffering {0}'.format(progress)) def displayErrorMessage(self): self.statusInfo(self.player.errorString()) def jump(self, index): if index.isValid(): self.playlist.setCurrentIndex(index.row()) self.player.play() def seek(self, seconds): self.player.setPosition(seconds * 1000) def previousAction(self): self.playlist.previous() def close(self): choice = Qt.QMessageBox.question( self, 'Close', 'Close the app?', Qt.QMessageBox.Yes | Qt.QMessageBox.No) if choice == Qt.QMessageBox.Yes: sys.exit() def open(self): names, _ = Qt.QFileDialog.getOpenFileNames(self, 'Open Files') # ['/home/milka/Documents/MusicPlayer/song.mp3'] self.addToPlaylist(names) def addToPlaylist(self, names): for name in names: fileInfo = Qt.QFileInfo(name) if fileInfo.exists(): url = QtCore.QUrl.fromLocalFile(fileInfo.absoluteFilePath()) # save_to_db song url create_song( url.path(), self.duration, playlist_name=self.name) if fileInfo.suffix().lower() == 'm3u': self.playlist.load(url) else: self.playlist.addMedia(Qt.QMediaContent(url)) else: url = QtCore.QUrl(name) if url.isValid(): self.playlist.addMedia(Qt.QMediaContent(url))
class MainWindowAction(QMainWindow, Ui_MainWindow): def __init__(self, parent=None): super(MainWindowAction, self).__init__(parent) self.player = QMediaPlayer() self.playlist = QMediaPlaylist() self.local_music_path = [] self.setupUi(self) self.init() self.show() def init(self): # self.setWindowFlags(Qt.FramelessWindowHint) self.loadParams() self.playlist.setPlaybackMode(self.playlist.Loop) self.player.setPlaylist(self.playlist) self.player.play() exit_normal_icon_path = QUrl.fromLocalFile(EXIT_ICON_PATH) self.exit_normal_icon = QIcon(EXIT_ICON_PATH) self.exitButton.setStyleSheet(EXIT_BUTTON_STYLE) self.exitButton.clicked.connect(self.close) self.minButton.clicked.connect(self.showMinimized) # self.playButton.clicked.connect(self.playControl) self.nextButton.clicked.connect(self.playlist.next) self.prevButton.clicked.connect(self.playlist.previous) self.playButton.clicked.connect(self.controlPlay) self.player.currentMediaChanged.connect(self.initProgressBar) self.player.stateChanged.connect(self.changePlayState) self.player.positionChanged.connect(self.changeBar) self.playProgressBar.sliderReleased.connect(self.changePlayPosition) def loadParams(self): with open(CONFIG_PATH, 'r') as file: params = json.load(file) self.local_music_dirs = params['initParams']['LocalMusicDirs'] last_playlist = params['lastPlayParams']['Playlist'] self.initPlayList(last_playlist) def initPlayList(self, playlist_name): playlist_path = './PlayList/' + playlist_name + '.json' with open(playlist_path, 'r', encoding='UTF-8') as file: music_list = json.load(file) music_path_list = music_list['Songs'] for music_path in music_path_list: path = QUrl.fromLocalFile(music_path) music = QMediaContent(path) self.playlist.addMedia(music) def controlPlay(self): if self.player.state() == self.player.PlayingState: self.player.pause() # self.playButton.setText("Play") elif self.player.state() == self.player.PausedState: self.player.play() elif self.player.state() == self.player.StoppedState: if self.player.mediaStatus() in [ self.player.LoadingMedia, self.player.LoadedMedia, self.player.BufferedMedia, self.player.BufferingMedia ]: self.player.play() def changePlayState(self): if self.player.state() == self.player.PlayingState: self.playButton.setText("Pause") else: self.playButton.setText("Play") def initProgressBar(self): print(self.playlist.currentMedia().resources()[0].url().fileName()) self.playProgressBar.setValue(0) def changeBar(self): if self.player.state() == self.player.PlayingState: duration = self.player.duration() if duration > 0: value = self.player.position() * 100 // duration self.playProgressBar.setValue(value) def changePlayPosition(self): self.player.pause() duration = self.player.duration() value = self.playProgressBar.value() * duration // 100 self.player.setPosition(value) self.player.play()
class MyWidget(QMainWindow): def __init__(self): super().__init__() # !Костыль # Запрещаю менять размер окна, т.к. не хочу работать с layout`ами self.setFixedSize(656, 532) self.setWindowIcon(QIcon('icons/icon.ico')) # Добавляем эквалайзер громкости self.equalizer = QVolumeEq((255, 255, 102), (255, 26, 10), bg_color=(0, 0, 0, 20)) self.equalizer.setParent(self) self.equalizer.move(20, 391) self.equalizer.resize(341, 31) uic.loadUi('icons/djap.ui', self) self.lightThemeAction.triggered.connect(self.change_theme) self.darkThemeAction.triggered.connect(self.change_theme) # Создаём организатор плейлистов self.playlist_handler = QPlaylistHandler() self.playlist_handler.setParent(self) self.playlist_handler.move(380, 40) # Настраиваем меню self.saveOption.triggered.connect(self.playlist_handler.save_playlist) self.saveAsOption.triggered.connect(self.playlist_handler.save_playlist_as) self.deleteOption.triggered.connect(self.playlist_handler.delete_playlist) self.aboutOption.triggered.connect(self.about) self.helpOption.triggered.connect(self.help) self.repeatModeOption.triggered.connect(self.playlist_handler.change_playmode) self.oneModeOption.triggered.connect(self.playlist_handler.change_playmode) self.randomModeOption.triggered.connect(self.playlist_handler.change_playmode) # Реализация проигрывателя и основного плейлиста self.player = QMediaPlayer() self.player.durationChanged.connect(self.update_song) self.player.setVolume(25) self.player.positionChanged.connect(self.update_timeline_position) self.queue = QMediaPlaylist(self.player) self.player.setPlaylist(self.queue) self.queue.setPlaybackMode(QMediaPlaylist.Loop) self.is_looped_queue = True # Загрузка музыки из плейлиста self.load_songs_from_playlist() # Подключаем кнопки к их функциям self.is_playing = False self.playBtn.clicked.connect(self.play_or_pause) self.queue.currentMediaChanged.connect(self.check_to_stop) self.nextBtn.clicked.connect(self.next_audio) self.prevBtn.clicked.connect(self.prev_audio) self.is_looped_current_track = False self.loopBtn.clicked.connect(self.loop_or_unloop_current_track) # Настройка слайдера звука self.volumeSlider.hide() self.volumeSlider.setValue(25) self.equalizer.setValue(25) self.volumeSlider.sliderReleased.connect(self.volumeSlider.hide) self.volumeSlider.valueChanged.connect(self.change_volume) self.volumeBtn.clicked.connect(self.change_volume) # Настройка таймлайна self.is_timeline_dragged = False self.timeline.sliderReleased.connect(self.timeline_changed) self.timeline.sliderPressed.connect(self.timeline_is_dragged) # !Костыль # Имитируем запуск аудиодорожки, чтобы подгрузить данные self.play_or_pause() self.play_or_pause() self.icon_changed() def palette(self): """Функция для создания темы""" con = sqlite3.connect('user_data.sqlite') cur = con.cursor() if int(cur.execute('SELECT * FROM theme').fetchone()[0]): palette = QPalette() palette.setColor(QPalette.Window, QColor(240, 240, 240)) palette.setColor(QPalette.WindowText, Qt.black) palette.setColor(QPalette.Base, Qt.white) palette.setColor(QPalette.AlternateBase, QColor(246, 246, 246)) palette.setColor(QPalette.ToolTipBase, QColor(255, 255, 240)) palette.setColor(QPalette.ToolTipText, Qt.black) palette.setColor(QPalette.Text, Qt.black) palette.setColor(QPalette.Button, QColor(240, 240, 240)) palette.setColor(QPalette.ButtonText, Qt.black) palette.setColor(QPalette.BrightText, Qt.white) palette.setColor(QPalette.Highlight, QColor(0, 120, 215).lighter()) palette.setColor(QPalette.HighlightedText, Qt.white) else: palette = QPalette() palette.setColor(QPalette.Window, QColor(53, 53, 53)) palette.setColor(QPalette.WindowText, Qt.white) palette.setColor(QPalette.Base, QColor(15, 15, 15)) palette.setColor(QPalette.AlternateBase, QColor(53, 53, 53)) palette.setColor(QPalette.ToolTipBase, Qt.white) palette.setColor(QPalette.ToolTipText, Qt.white) palette.setColor(QPalette.Text, Qt.white) palette.setColor(QPalette.Button, QColor(53, 53, 53)) palette.setColor(QPalette.ButtonText, Qt.white) palette.setColor(QPalette.BrightText, Qt.red) palette.setColor(QPalette.Highlight, QColor(142, 45, 197).lighter()) palette.setColor(QPalette.HighlightedText, Qt.black) return palette def change_theme(self): """Функция для смены темы""" con = sqlite3.connect('user_data.sqlite') cur = con.cursor() if self.sender() == self.lightThemeAction: cur.execute('UPDATE theme SET isit = 1') else: cur.execute('UPDATE theme SET isit = 0') con.commit() QMessageBox.warning(self, 'DJust Audio Player', 'Чтобы изменения вступили в силу, ' 'перезапустите приложение.', QMessageBox.Ok) def help(self): """Функция для показа формы справки""" self.help = QHelp() def about(self): """Функция для показа формы О программе""" self.about = QAbout() def delete_song_from_mediaplayer(self, index): """Удалить трек из медиаплеера""" self.queue.removeMedia(index) def add_song_to_mediaplayer(self, url): """Добавить трек в медиаплеер""" self.queue.addMedia(QMediaContent(QUrl(url))) def change_track_by_click(self, row): """Функция для смены трека по нажатию в списке""" self.queue.setCurrentIndex(row) def check_to_stop(self): """Проверяем, чтобы плеер не играл с пустым плейлистом""" if self.queue.isEmpty() and self.is_playing: self.play_or_pause() def load_songs_from_playlist(self): """Загрузка музыки из БД в плейлист""" self.queue.clear() for url in self.playlist_handler.urls(): self.queue.addMedia(QMediaContent(QUrl(url))) def icon_changed(self): """Функция для вывода обложки трека""" def noicon(): """В случае отсутствия обложки эта функция ставить свою заглушку""" try: pixmap = QPixmap() if pixmap.load('icons/noicon.png'): self.audioPic.setPixmap(pixmap) except Exception as e: print(e.__class__.__name__, ': ', e, sep='') try: # Читаем метаданные трека n = self.queue.currentIndex() url = self.playlist_handler.urls()[n if n > -1 else 0] file = File(url) for i in file.tags.keys(): if 'APIC:' in i: artwork = file.tags[i].data break else: raise KeyError # Переводим их в байтовый массив ba = QByteArray(artwork) # И загружаем на форму, если это возможно pixmap = QPixmap() if pixmap.loadFromData(ba): self.audioPic.setPixmap(pixmap.scaled(341, 341, Qt.IgnoreAspectRatio)) else: raise KeyError except Exception as e: # print(e.__class__.__name__, ': ', e, sep='') noicon() def timeline_is_dragged(self): """Мини-функция для изменения переменной""" # При вызове этой функции мы понимаем, что пользователь # взаимодействует с таймлайном трека self.is_timeline_dragged = True def timeline_changed(self): """Функция для пользовательской перемотки данного трека""" # Перематываем позицию плеера self.player.setPosition(self.timeline.value() * 1000) # Пользователь отпустил язычок слайдера и больше не взаимодействует с таймлайном self.is_timeline_dragged = False # Вызываем обновление временной шкалы, т.к. произошла перемотка self.update_timeline_position() def update_song(self): """Изменение данных о треке""" # !Костыль # Проматываем несколько миллисекунд, чтобы избежать повреждённых треков self.player.setPosition(10) # Меняем обложку self.icon_changed() # Выделяем в списке новый трек self.playlist_handler.set_current_select(self.queue.currentIndex()) # Меняем название окна в соответствии с играющим треком title = self.queue.currentMedia().canonicalUrl().path().split('/')[-1] if title: self.setWindowTitle('DJust Audio Player | %s' % title) else: self.setWindowTitle('DJust Audio Player') # Изменяем длину таймлайна на длину трека self.timeline.setMaximum(self.player.duration() // 1000) # Выводим длину трека в минутах/секундах на экран minutes, seconds = self.player.duration() // 1000 // 60, self.player.duration() // 1000 % 60 self.endTimeLabel.setText(str(minutes) + ':{:02d}'.format(seconds)) def update_timeline_position(self): """Функция для обновления временной шкалы""" # Выводим текущее положение плеера в минутах/секундах minutes, seconds = self.player.position() // 1000 // 60, self.player.position() // 1000 % 60 self.currentTimeLabel.setText(str(minutes) + ':{:02d}'.format(seconds)) # Чтобы не "вырывать" язычок слайдера из рук пользователя, # проверяем, что пользователь НЕ взаимодейтсвует с таймлайном. if not self.is_timeline_dragged: self.timeline.setValue(minutes * 60 + seconds) def loop_or_unloop_current_track(self): """Мини-функция для зацикливания данного трека""" if not self.is_looped_current_track: # Зацикливаем self.is_looped_current_track = True self.queue.setPlaybackMode(QMediaPlaylist.CurrentItemInLoop) # Меняем картинку на перечёркнутый круг self.loopBtn.setStyleSheet('background-image: url(icons/unloop.png)') else: # убираем цикл self.is_looped_current_track = False self.queue.setPlaybackMode(self.playlist_handler.mode) self.loopBtn.setStyleSheet('background-image: url(icons/loop.png)') def next_audio(self): """Функция для перемотки на следующий в списке трек""" if self.queue.mediaCount() - 1 == self.queue.currentIndex(): # Если трек ппоследний в списке, возвращаемся к первому self.queue.setCurrentIndex(0) else: # Иначе просто перемещаемся к следующему self.queue.next() def prev_audio(self): """Функция для перемотки на предыдущий в списке трек""" if 0 == self.queue.currentIndex(): # Если трек первый в списке, возвращаемся к последнему self.queue.setCurrentIndex(self.queue.mediaCount() - 1) else: # Иначе просто возвращаемся к предыдущему self.queue.previous() def play_or_pause(self): """Функция для запуска или остановки проигрывателя""" if self.queue.isEmpty(): # Меняем картинку на стрелочку (проигрывание) self.is_playing = False self.playBtn.setStyleSheet('background-image: url(icons/play.png)') # Ставим на паузу self.player.pause() return if self.is_playing: # Меняем картинку на стрелочку (проигрывание) self.is_playing = False self.playBtn.setStyleSheet('background-image: url(icons/play.png)') # Ставим на паузу self.player.pause() else: # Меняем картинку на 2 палочки (пауза) self.is_playing = True self.playBtn.setStyleSheet('background-image: url(icons/pause.png)') # Запускаем звук self.player.play() def change_volume(self): """Мини-Функция для передачи уровня громкости в плеер""" # Функцию использует несколько объектов сразу, проверяем вызывателя if self.sender() == self.volumeBtn: # Если функцию вызвала кнопка, то включаем/выключаем отображение слайдера if not self.volumeSlider.isHidden(): self.volumeSlider.hide() else: self.volumeSlider.show() else: # Иначе функцию вызвал сам слайдер. Значит, меняем значение self.player.setVolume(self.volumeSlider.value()) self.equalizer.setValue(self.volumeSlider.value())
class VideoPlayer(QWidget): def __init__(self, aPath, parent=None): super(VideoPlayer, self).__init__(parent) self.setAttribute( Qt.WA_NoSystemBackground, True ) self.colorDialog = None self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.mediaPlayer.setVolume(80) self.videoWidget = QVideoWidget(self) self.lbl = QLineEdit('00:00:00') self.lbl.setReadOnly(True) self.lbl.setEnabled(False) self.lbl.setFixedWidth(60) self.lbl.setUpdatesEnabled(True) self.lbl.setStyleSheet(stylesheet(self)) self.elbl = QLineEdit('00:00:00') self.elbl.setReadOnly(True) self.elbl.setEnabled(False) self.elbl.setFixedWidth(60) self.elbl.setUpdatesEnabled(True) self.elbl.setStyleSheet(stylesheet(self)) self.playButton = QPushButton() self.playButton.setEnabled(False) self.playButton.setFixedWidth(32) self.playButton.setStyleSheet("background-color: black") self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay)) self.playButton.clicked.connect(self.play) self.positionSlider = QSlider(Qt.Horizontal, self) self.positionSlider.setStyleSheet (stylesheet(self)) self.positionSlider.setRange(0, 100) self.positionSlider.sliderMoved.connect(self.setPosition) self.positionSlider.sliderMoved.connect(self.handleLabel) self.positionSlider.setSingleStep(2) self.positionSlider.setPageStep(20) self.positionSlider.setAttribute(Qt.WA_TranslucentBackground, True) controlLayout = QHBoxLayout() controlLayout.setContentsMargins(5, 0, 5, 0) controlLayout.addWidget(self.playButton) controlLayout.addWidget(self.lbl) controlLayout.addWidget(self.positionSlider) controlLayout.addWidget(self.elbl) layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self.videoWidget) layout.addLayout(controlLayout) self.setLayout(layout) self.myinfo = "©2016\nAxel Schneider\n\nMouse Wheel = Zoom\nUP = Volume Up\nDOWN = Volume Down\n" + \ "LEFT = < 1 Minute\nRIGHT = > 1 Minute\n" + \ "SHIFT+LEFT = < 10 Minutes\nSHIFT+RIGHT = > 10 Minutes\nf = Fullscreen On/Off" self.widescreen = True self.setAcceptDrops(True) self.setWindowTitle("QT5 Player") self.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint) self.setGeometry(700, 400, 400, 290) self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu); self.customContextMenuRequested[QtCore.QPoint].connect(self.contextMenuRequested) self.hideSlider() self.show() self.playFromURL() #### shortcuts #### self.shortcut = QShortcut(QKeySequence("q"), self) self.shortcut.activated.connect(self.handleQuit) self.shortcut = QShortcut(QKeySequence("u"), self) self.shortcut.activated.connect(self.playFromURL) self.shortcut = QShortcut(QKeySequence("o"), self) self.shortcut.activated.connect(self.openFile) self.shortcut = QShortcut(QKeySequence(" "), self) self.shortcut.activated.connect(self.play) self.shortcut = QShortcut(QKeySequence("f"), self) self.shortcut.activated.connect(self.handleFullscreen) self.shortcut = QShortcut(QKeySequence("i"), self) self.shortcut.activated.connect(self.handleInfo) self.shortcut = QShortcut(QKeySequence("s"), self) self.shortcut.activated.connect(self.toggleSlider) self.shortcut = QShortcut(QKeySequence(Qt.Key_Right), self) self.shortcut.activated.connect(self.forwardSlider) self.shortcut = QShortcut(QKeySequence(Qt.Key_Left), self) self.shortcut.activated.connect(self.backSlider) self.shortcut = QShortcut(QKeySequence(Qt.Key_Up), self) self.shortcut.activated.connect(self.volumeUp) self.shortcut = QShortcut(QKeySequence(Qt.Key_Down), self) self.shortcut.activated.connect(self.volumeDown) self.shortcut = QShortcut(QKeySequence(Qt.ShiftModifier + Qt.Key_Right) , self) self.shortcut.activated.connect(self.forwardSlider10) self.shortcut = QShortcut(QKeySequence(Qt.ShiftModifier + Qt.Key_Left) , self) self.shortcut.activated.connect(self.backSlider10) self.shortcut = QShortcut(QKeySequence("c") , self) self.shortcut.activated.connect(self.showColorDialog) self.mediaPlayer.setVideoOutput(self.videoWidget) self.mediaPlayer.stateChanged.connect(self.mediaStateChanged) self.mediaPlayer.positionChanged.connect(self.positionChanged) self.mediaPlayer.positionChanged.connect(self.handleLabel) self.mediaPlayer.durationChanged.connect(self.durationChanged) self.mediaPlayer.error.connect(self.handleError) def openFile(self): fileName, _ = QFileDialog.getOpenFileName(self, "Open Movie", QDir.homePath(), "Videos (*.mp4 *.ts *.avi *.mpeg *.mpg *.mkv *.VOB *.m4v)") if fileName != '': self.loadFilm(fileName) print("File loaded") def playFromURL(self): self.mediaPlayer.pause() clip = QApplication.clipboard() myurl = clip.text() if myurl.startswith("http"): self.mediaPlayer.setMedia(QMediaContent(QUrl(myurl))) elif myurl.startswith("/"): self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile(myurl))) else: return self.playButton.setEnabled(True) self.mediaPlayer.play() self.hideSlider() print(myurl) def play(self): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.mediaPlayer.pause() else: self.mediaPlayer.play() def mediaStateChanged(self, state): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.playButton.setIcon( self.style().standardIcon(QStyle.SP_MediaPause)) else: self.playButton.setIcon( self.style().standardIcon(QStyle.SP_MediaPlay)) def positionChanged(self, position): self.positionSlider.setValue(position) def durationChanged(self, duration): self.positionSlider.setRange(0, duration) mtime = QTime(0,0,0,0) mtime = mtime.addMSecs(self.mediaPlayer.duration()) self.elbl.setText(mtime.toString()) def setPosition(self, position): self.mediaPlayer.setPosition(position) def handleError(self): self.playButton.setEnabled(False) print("Error: " + self.mediaPlayer.errorString()) def handleQuit(self): self.mediaPlayer.stop() print("Goodbye ...") app.quit() def contextMenuRequested(self,point): menu = QtWidgets.QMenu() actionFile = menu.addAction("open File (o)") actionclipboard = menu.addSeparator() actionURL = menu.addAction("URL / File from Clipboard (u)") actionclipboard = menu.addSeparator() actionToggle = menu.addAction("show / hide Slider (s)") actionFull = menu.addAction("Fullscreen (f)") action169 = menu.addAction("16 : 9") action43 = menu.addAction("4 : 3") actionColors = menu.addAction("Color Options (c)") actionSep = menu.addSeparator() actionInfo = menu.addAction("Info (i)") actionsep2 = menu.addSeparator() actionQuit = menu.addAction("Exit (q)") actionFile.triggered.connect(self.openFile) actionQuit.triggered.connect(self.handleQuit) actionFull.triggered.connect(self.handleFullscreen) actionInfo.triggered.connect(self.handleInfo) actionToggle.triggered.connect(self.toggleSlider) actionURL.triggered.connect(self.playFromURL) action169.triggered.connect(self.screen169) action43.triggered.connect(self.screen43) actionColors.triggered.connect(self.showColorDialog) menu.exec_(self.mapToGlobal(point)) def wheelEvent(self,event): mwidth = self.frameGeometry().width() mheight = self.frameGeometry().height() mleft = self.frameGeometry().left() mtop = self.frameGeometry().top() mscale = event.angleDelta().y() / 5 if self.widescreen == True: self.setGeometry(mleft, mtop, mwidth + mscale, (mwidth + mscale) / 1.778) else: self.setGeometry(mleft, mtop, mwidth + mscale, (mwidth + mscale) / 1.33) def screen169(self): self.widescreen = True mwidth = self.frameGeometry().width() mheight = self.frameGeometry().height() mleft = self.frameGeometry().left() mtop = self.frameGeometry().top() mratio = 1.778 self.setGeometry(mleft, mtop, mwidth, mwidth / mratio) def screen43(self): self.widescreen = False mwidth = self.frameGeometry().width() mheight = self.frameGeometry().height() mleft = self.frameGeometry().left() mtop = self.frameGeometry().top() mratio = 1.33 self.setGeometry(mleft, mtop, mwidth, mwidth / mratio) def handleFullscreen(self): if self.windowState() & QtCore.Qt.WindowFullScreen: self.showNormal() print("no Fullscreen") else: self.showFullScreen() print("Fullscreen entered") def handleInfo(self): msg = QMessageBox() msg.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.SplashScreen) msg.setGeometry(self.frameGeometry().left() + 30, self.frameGeometry().top() + 30, 300, 400) msg.setIcon(QMessageBox.Information) msg.setText("QT5 Player") msg.setInformativeText(self.myinfo) msg.setStandardButtons(QMessageBox.Close) msg.exec() def toggleSlider(self): if self.positionSlider.isVisible(): self.hideSlider() else: self.showSlider() def hideSlider(self): self.playButton.hide() self.lbl.hide() self.positionSlider.hide() self.elbl.hide() mwidth = self.frameGeometry().width() mheight = self.frameGeometry().height() mleft = self.frameGeometry().left() mtop = self.frameGeometry().top() if self.widescreen == True: self.setGeometry(mleft, mtop, mwidth, mwidth / 1.778) else: self.setGeometry(mleft, mtop, mwidth, mwidth / 1.33) def showSlider(self): self.playButton.show() self.lbl.show() self.positionSlider.show() self.elbl.show() mwidth = self.frameGeometry().width() mheight = self.frameGeometry().height() mleft = self.frameGeometry().left() mtop = self.frameGeometry().top() self.positionSlider.setFocus() if self.widescreen == True: self.setGeometry(mleft, mtop, mwidth, mwidth / 1.55) else: self.setGeometry(mleft, mtop, mwidth, mwidth / 1.33) def forwardSlider(self): self.mediaPlayer.setPosition(self.mediaPlayer.position() + 1000*60) def forwardSlider10(self): self.mediaPlayer.setPosition(self.mediaPlayer.position() + 10000*60) def backSlider(self): self.mediaPlayer.setPosition(self.mediaPlayer.position() - 1000*60) def backSlider10(self): self.mediaPlayer.setPosition(self.mediaPlayer.position() - 10000*60) def volumeUp(self): self.mediaPlayer.setVolume(self.mediaPlayer.volume() + 10) print("Volume: " + str(self.mediaPlayer.volume())) def volumeDown(self): self.mediaPlayer.setVolume(self.mediaPlayer.volume() - 10) print("Volume: " + str(self.mediaPlayer.volume())) def mouseMoveEvent(self, event): if event.buttons() == Qt.LeftButton: self.move(event.globalPos() \ - QPoint(self.frameGeometry().width() / 2, \ self.frameGeometry().height() / 2)) event.accept() def dragEnterEvent(self, event): if event.mimeData().hasUrls(): event.accept() elif event.mimeData().hasFormat('text/plain'): event.accept() else: event.ignore() ########### drag files ############# def dropEvent(self, event): if event.mimeData().hasUrls(): f = str(event.mimeData().urls()[0].toLocalFile()) self.loadFilm(f) elif event.mimeData().hasText(): f = str(event.mimeData().text()) self.mediaPlayer.setMedia(QMediaContent(QUrl(f))) self.mediaPlayer.play() def loadFilm(self, f): self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile(f))) self.playButton.setEnabled(True) self.mediaPlayer.play() print(str(self.mediaPlayer.media().canonicalResource().resolution())) def openFileAtStart(self, filelist): matching = [s for s in filelist if ".myformat" in s] if len(matching) > 0: self.loadFilm(matching) ##################### update Label ################################## def handleLabel(self): self.lbl.clear() mtime = QTime(0,0,0,0) self.time = mtime.addMSecs(self.mediaPlayer.position()) self.lbl.setText(self.time.toString()) ################################################################### def showColorDialog(self): if self.colorDialog is None: brightnessSlider = QSlider(Qt.Horizontal) brightnessSlider.setRange(-100, 100) brightnessSlider.setValue(self.videoWidget.brightness()) brightnessSlider.sliderMoved.connect( self.videoWidget.setBrightness) self.videoWidget.brightnessChanged.connect( brightnessSlider.setValue) contrastSlider = QSlider(Qt.Horizontal) contrastSlider.setRange(-100, 100) contrastSlider.setValue(self.videoWidget.contrast()) contrastSlider.sliderMoved.connect(self.videoWidget.setContrast) self.videoWidget.contrastChanged.connect(contrastSlider.setValue) hueSlider = QSlider(Qt.Horizontal) hueSlider.setRange(-100, 100) hueSlider.setValue(self.videoWidget.hue()) hueSlider.sliderMoved.connect(self.videoWidget.setHue) self.videoWidget.hueChanged.connect(hueSlider.setValue) saturationSlider = QSlider(Qt.Horizontal) saturationSlider.setRange(-100, 100) saturationSlider.setValue(self.videoWidget.saturation()) saturationSlider.sliderMoved.connect( self.videoWidget.setSaturation) self.videoWidget.saturationChanged.connect( saturationSlider.setValue) layout = QFormLayout() layout.addRow("Brightness", brightnessSlider) layout.addRow("Contrast", contrastSlider) layout.addRow("Hue", hueSlider) layout.addRow("Saturation", saturationSlider) button = QPushButton("Close Window") button.setFixedWidth(120) layout.addRow(button) self.colorDialog = QDialog(self) self.colorDialog.setWindowTitle("Color Options") self.colorDialog.setLayout(layout) button.clicked.connect(self.colorDialog.close) self.colorDialog.setGeometry(300, 250, 300, 100) self.colorDialog.show()
class MP3Player(QWidget): def __init__(self): super().__init__() self.startTimeLabel = QLabel('00:00') self.endTimeLabel = QLabel('00:00') self.slider = QSlider(Qt.Horizontal, self) self.PlayModeBtn = QPushButton(self) self.playBtn = QPushButton(self) self.prevBtn = QPushButton(self) self.nextBtn = QPushButton(self) self.openBtn = QPushButton(self) self.musicList = QListWidget() self.song_formats = ['mp3', 'm4a', 'flac', 'wav', 'ogg'] self.songs_list = [] self.cur_playing_song = '' self.is_pause = True self.player = QMediaPlayer() self.is_switching = False self.playMode = 0 self.settingfilename = 'config.ini' self.textLable = QLabel('前进的路上,也要记得欣赏沿途的风景呀!') self.infoLabel = QLabel('Mculover666 v2.0.0') self.playBtn.setStyleSheet( "QPushButton{border-image: url(resource/image/play.png)}") self.playBtn.setFixedSize(48, 48) self.nextBtn.setStyleSheet( "QPushButton{border-image: url(resource/image/next.png)}") self.nextBtn.setFixedSize(48, 48) self.prevBtn.setStyleSheet( "QPushButton{border-image: url(resource/image/prev.png)}") self.prevBtn.setFixedSize(48, 48) self.openBtn.setStyleSheet( "QPushButton{border-image: url(resource/image/open.png)}") self.openBtn.setFixedSize(24, 24) self.PlayModeBtn.setStyleSheet( "QPushButton{border-image: url(resource/image/sequential.png)}") self.PlayModeBtn.setFixedSize(24, 24) self.timer = QTimer(self) self.timer.start(1000) self.timer.timeout.connect(self.playByMode) self.hBoxSlider = QHBoxLayout() self.hBoxSlider.addWidget(self.startTimeLabel) self.hBoxSlider.addWidget(self.slider) self.hBoxSlider.addWidget(self.endTimeLabel) self.hBoxButton = QHBoxLayout() self.hBoxButton.addWidget(self.PlayModeBtn) self.hBoxButton.addStretch(1) self.hBoxButton.addWidget(self.prevBtn) self.hBoxButton.addWidget(self.playBtn) self.hBoxButton.addWidget(self.nextBtn) self.hBoxButton.addStretch(1) self.hBoxButton.addWidget(self.openBtn) self.vBoxControl = QVBoxLayout() self.vBoxControl.addLayout(self.hBoxSlider) self.vBoxControl.addLayout(self.hBoxButton) self.hBoxAbout = QHBoxLayout() self.hBoxAbout.addWidget(self.textLable) self.hBoxAbout.addStretch(1) self.hBoxAbout.addWidget(self.infoLabel) self.vboxMain = QVBoxLayout() self.vboxMain.addWidget(self.musicList) self.vboxMain.addLayout(self.vBoxControl) self.vboxMain.addLayout(self.hBoxAbout) self.setLayout(self.vboxMain) self.openBtn.clicked.connect(self.openMusicFloder) self.playBtn.clicked.connect(self.playMusic) self.prevBtn.clicked.connect(self.prevMusic) self.nextBtn.clicked.connect(self.nextMusic) self.musicList.itemDoubleClicked.connect(self.doubleClicked) self.slider.sliderMoved[int].connect( lambda: self.player.setPosition(self.slider.value())) self.PlayModeBtn.clicked.connect(self.playModeSet) self.loadingSetting() self.initUI() # 初始化界面 def initUI(self): self.resize(600, 400) self.center() self.setWindowTitle('音乐播放器') self.setWindowIcon(QIcon('resource/image/favicon.ico')) self.show() # 窗口显示居中 def center(self): qr = self.frameGeometry() cp = QDesktopWidget().availableGeometry().center() qr.moveCenter(cp) self.move(qr.topLeft()) # 打开文件夹 def openMusicFloder(self): self.cur_path = QFileDialog.getExistingDirectory(self, "选取音乐文件夹", './') if self.cur_path: self.showMusicList() self.cur_playing_song = '' self.startTimeLabel.setText('00:00') self.endTimeLabel.setText('00:00') self.slider.setSliderPosition(0) self.updateSetting() self.is_pause = True self.playBtn.setStyleSheet( "QPushButton{border-image: url(resource/image/play.png)}") # 显示音乐列表 def showMusicList(self): self.musicList.clear() for song in os.listdir(self.cur_path): if song.split('.')[-1] in self.song_formats: self.songs_list.append([ song, os.path.join(self.cur_path, song).replace('\\', '/') ]) self.musicList.addItem(song) self.musicList.setCurrentRow(0) if self.songs_list: self.cur_playing_song = self.songs_list[ self.musicList.currentRow()][-1] # 提示 def Tips(self, message): QMessageBox.about(self, "提示", message) # 设置当前播放的音乐 def setCurPlaying(self): self.cur_playing_song = self.songs_list[ self.musicList.currentRow()][-1] self.player.setMedia(QMediaContent(QUrl(self.cur_playing_song))) # 播放/暂停播放 def playMusic(self): if self.musicList.count() == 0: self.Tips('当前路径内无可播放的音乐文件') return if not self.player.isAudioAvailable(): self.setCurPlaying() if self.is_pause or self.is_switching: self.player.play() self.is_pause = False self.playBtn.setStyleSheet( "QPushButton{border-image: url(resource/image/pause.png)}") elif (not self.is_pause) and (not self.is_switching): self.player.pause() self.is_pause = True self.playBtn.setStyleSheet( "QPushButton{border-image: url(resource/image/play.png)}") # 上一曲 def prevMusic(self): self.slider.setValue(0) if self.musicList.count() == 0: self.Tips('当前路径内无可播放的音乐文件') return pre_row = self.musicList.currentRow() - 1 if self.musicList.currentRow( ) != 0 else self.musicList.count() - 1 self.musicList.setCurrentRow(pre_row) self.is_switching = True self.setCurPlaying() self.playMusic() self.is_switching = False # 下一曲 def nextMusic(self): self.slider.setValue(0) if self.musicList.count() == 0: self.Tips('当前路径内无可播放的音乐文件') return next_row = self.musicList.currentRow( ) + 1 if self.musicList.currentRow( ) != self.musicList.count() - 1 else 0 self.musicList.setCurrentRow(next_row) self.is_switching = True self.setCurPlaying() self.playMusic() self.is_switching = False # 双击歌曲名称播放音乐 def doubleClicked(self): self.slider.setValue(0) self.is_switching = True self.setCurPlaying() self.playMusic() self.is_switching = False # 根据播放模式自动播放,并刷新进度条 def playByMode(self): # 刷新进度条 if (not self.is_pause) and (not self.is_switching): self.slider.setMinimum(0) self.slider.setMaximum(self.player.duration()) self.slider.setValue(self.slider.value() + 1000) self.startTimeLabel.setText( time.strftime('%M:%S', time.localtime(self.player.position() / 1000))) self.endTimeLabel.setText( time.strftime('%M:%S', time.localtime(self.player.duration() / 1000))) # 顺序播放 if (self.playMode == 0) and (not self.is_pause) and (not self.is_switching): if self.musicList.count() == 0: return if self.player.position() == self.player.duration(): self.nextMusic() # 单曲循环 elif (self.playMode == 1) and (not self.is_pause) and (not self.is_switching): if self.musicList.count() == 0: return if self.player.position() == self.player.duration(): self.is_switching = True self.setCurPlaying() self.slider.setValue(0) self.playMusic() self.is_switching = False # 随机播放 elif (self.playMode == 2) and (not self.is_pause) and (not self.is_switching): if self.musicList.count() == 0: return if self.player.position() == self.player.duration(): self.is_switching = True self.musicList.setCurrentRow( random.randint(0, self.musicList.count() - 1)) self.setCurPlaying() self.slider.setValue(0) self.playMusic() self.is_switching = False # 更新配置文件 def updateSetting(self): config = configparser.ConfigParser() config.read(self.settingfilename) if not os.path.isfile(self.settingfilename): config.add_section('MP3Player') config.set('MP3Player', 'PATH', self.cur_path) config.write(open(self.settingfilename, 'w')) # 加载配置文件 def loadingSetting(self): config = configparser.ConfigParser() config.read(self.settingfilename) if not os.path.isfile(self.settingfilename): return self.cur_path = config.get('MP3Player', 'PATH') self.showMusicList() # 播放模式设置 def playModeSet(self): # 设置为单曲循环模式 if self.playMode == 0: self.playMode = 1 self.PlayModeBtn.setStyleSheet( "QPushButton{border-image: url(resource/image/circulation.png)}" ) # 设置为随机播放模式 elif self.playMode == 1: self.playMode = 2 self.PlayModeBtn.setStyleSheet( "QPushButton{border-image: url(resource/image/random.png)}") # 设置为顺序播放模式 elif self.playMode == 2: self.playMode = 0 self.PlayModeBtn.setStyleSheet( "QPushButton{border-image: url(resource/image/sequential.png)}" ) # 确认用户是否要真正退出 def closeEvent(self, event): reply = QMessageBox.question(self, 'Message', "确定要退出吗?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: event.accept() else: event.ignore()
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 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 ApplicationWindow(QMainWindow): ## Accessing files in Processed Stuff ## QDir.setCurrent(QCoreApplication.applicationDirPath()) processedVideoPath = QDir.currentPath() + "/ProcessedStuff/horses_1_predicted.mp4"; textFilePath = QDir.currentPath() + "/ProcessedStuff/labels_example.txt"; # Environmental Variable # os.environ['PYTHONPATH'] = "$(pwd)/detection:$(pwd)/detection/slim" # subprocess.check_call(['sqsub', '-np', sys.argv[1], 'application.py'], # env=dict(os.environ, SQSUB_VAR="visible in this subprocess")) ## Important variables ## videoLoaded = False fileReceived = False playing = False fileName = None labels = [] nextLine = 0 def __init__(self): # Create the Qt5 application backend super(ApplicationWindow, self).__init__() # Load in and display the UI self.ui = Ui_MainWindow() self.ui.setupUi(self) ## CONNECT EVENTS (like button presses) to functions ## self.ui.button_play_pause.clicked.connect(self.playPauseButtonClicked) self.ui.button_load.clicked.connect(self.loadButtonClicked) self.ui.button_track.clicked.connect(self.trackButtonClicked) # Configure the original video widget self.original_video_player = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.original_video_player.durationChanged.connect(self.durationChanged) self.original_video_player.setVideoOutput(self.ui.original_video_widget) # Configure the processed video widget self.video_player = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.video_player.setNotifyInterval(30) self.video_player.durationChanged.connect(self.durationChanged) self.video_player.positionChanged.connect(self.positionChanged) self.video_player.stateChanged.connect(self.stopped) self.video_player.setVideoOutput(self.ui.video_widget) # Configure the video slider self.ui.video_slider.sliderPressed.connect(self.sliderPressed) self.ui.video_slider.sliderReleased.connect(self.sliderReleased) # Update states self.updateStates() ## CALLBACK FUNCTIONS ## def playPauseButtonClicked(self): if self.playing: print("Pause!") self.pause() else: print("Play!") self.play() def saveButtonClicked(self): print("Save!") def loadButtonClicked(self): print("Load!") # fileName, _ = QFileDialog.getOpenFileName( # self, # "Choose a video", # QStandardPaths.writableLocation(QStandardPaths.DocumentsLocation), # "Vide files (*mp4 *mp3)") # file = open("ProcessedStuff/labels_example.txt","w") # file.write("labels = []\n") # file.close() fileName, _ = QFileDialog.getOpenFileName(self, "Open Files") if fileName != "": self.ui.file_info.setText(fileName) print("Video filepath: " + fileName) self.fileName = fileName self.fileReceived = True self.nextLine = 0 self.updateStates() def trackButtonClicked(self): print("Track!") # Do processing and call following method when completed # detection.detection_code(self.fileName) self.processingFinished() def sliderReleased(self): newPosition = self.ui.video_slider.value() self.setPosition(newPosition) def sliderPressed(self): self.pause() def durationChanged(self): self.videoLoaded = True self.updateStates() self.ui.video_slider.setMaximum(self.video_player.duration()) def positionChanged(self): if not self.playing: return position = self.video_player.position() # Update video progress bar self.ui.video_slider.setValue(position) # Update information label self.updateLabel(position) def stopped(self): if self.video_player.state() == QMediaPlayer.StoppedState: self.playing = False self.ui.label_info.setText("") ## Helper Functions ## def play(self): self.original_video_player.play() self.video_player.play() self.playing = True def pause(self): self.playing = False self.original_video_player.pause() self.video_player.pause() def setPosition(self, position): self.resetNextLine(position) self.updateLabel(position) self.original_video_player.setPosition(position) self.video_player.setPosition(position) self.play() def updateStates(self): self.ui.button_play_pause.setEnabled(self.videoLoaded) self.ui.video_slider.setEnabled(self.videoLoaded) self.ui.button_track.setEnabled(self.fileReceived and not self.playing) def processingFinished(self): print("Text file location: " + self.textFilePath) file = open(self.textFilePath, "r") self.labels = [line.split(',') for line in file] file.close() print(self.processedVideoPath) self.video_player.setMedia(QMediaContent(QUrl.fromLocalFile(self.processedVideoPath))) self.original_video_player.setMedia(QMediaContent(QUrl.fromLocalFile(self.fileName))) self.play() # When the user changes the slider the next line changes def resetNextLine(self, position): while (position < int(self.labels[self.nextLine][0])): self.nextLine -= 1 if (self.nextLine <= 0): break if self.nextLine+1<=len(self.labels)-1: while (position >= int(self.labels[self.nextLine+1][0])): self.nextLine += 1 if (self.nextLine >= len(self.labels)-1): break def updateLabel(self, position): if position >= int(self.labels[self.nextLine][0]): label = self.labels[self.nextLine] messageStr = "Count: " + label[1] for i in range(2,len(label),2): messageStr += ("\n%s. %s %s" % (i-int(i/2),label[i],label[i+1])) self.ui.label_info.setText(messageStr) if self.nextLine < len(self.labels)-1: self.nextLine += 1
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 VideoPlayer(QWidget): def __init__(self, aPath, parent=None): super(VideoPlayer, self).__init__(parent) self.setAttribute(Qt.WA_NoSystemBackground, True) self.setAcceptDrops(True) self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.StreamPlayback) self.mediaPlayer.mediaStatusChanged.connect(self.printMediaData) self.mediaPlayer.setVolume(80) self.videoWidget = QVideoWidget(self) self.lbl = QLineEdit('00:00:00') self.lbl.setReadOnly(True) self.lbl.setFixedWidth(70) self.lbl.setUpdatesEnabled(True) self.lbl.setStyleSheet(stylesheet(self)) self.elbl = QLineEdit('00:00:00') self.elbl.setReadOnly(True) self.elbl.setFixedWidth(70) self.elbl.setUpdatesEnabled(True) self.elbl.setStyleSheet(stylesheet(self)) self.playButton = QPushButton() self.playButton.setEnabled(False) self.playButton.setFixedWidth(32) self.playButton.setStyleSheet("background-color: black") self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay)) self.playButton.clicked.connect(self.play) self.positionSlider = QSlider(Qt.Horizontal, self) self.positionSlider.setStyleSheet(stylesheet(self)) self.positionSlider.setRange(0, 100) self.positionSlider.sliderMoved.connect(self.setPosition) self.positionSlider.sliderMoved.connect(self.handleLabel) self.positionSlider.setSingleStep(2) self.positionSlider.setPageStep(20) self.positionSlider.setAttribute(Qt.WA_TranslucentBackground, True) self.clip = QApplication.clipboard() self.process = QProcess(self) self.process.readyRead.connect(self.dataReady) # self.process.started.connect(lambda: print("grabbing YouTube URL")) self.process.finished.connect(self.playFromURL) self.myurl = "" controlLayout = QHBoxLayout() controlLayout.setContentsMargins(5, 0, 5, 0) controlLayout.addWidget(self.playButton) controlLayout.addWidget(self.lbl) controlLayout.addWidget(self.positionSlider) controlLayout.addWidget(self.elbl) layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self.videoWidget) layout.addLayout(controlLayout) self.setLayout(layout) self.myinfo = "©2016\nAxel Schneider\n\nMouse Wheel = Zoom\nUP = Volume Up\nDOWN = Volume Down\n" + \ "LEFT = < 1 Minute\nRIGHT = > 1 Minute\n" + \ "SHIFT+LEFT = < 10 Minutes\nSHIFT+RIGHT = > 10 Minutes" self.widescreen = True #### shortcuts #### self.shortcut = QShortcut(QKeySequence("q"), self) self.shortcut.activated.connect(self.handleQuit) self.shortcut = QShortcut(QKeySequence("u"), self) self.shortcut.activated.connect(self.playFromURL) self.shortcut = QShortcut(QKeySequence("y"), self) self.shortcut.activated.connect(self.getYTUrl) self.shortcut = QShortcut(QKeySequence("o"), self) self.shortcut.activated.connect(self.openFile) self.shortcut = QShortcut(QKeySequence(" "), self) self.shortcut.activated.connect(self.play) self.shortcut = QShortcut(QKeySequence("f"), self) self.shortcut.activated.connect(self.handleFullscreen) self.shortcut = QShortcut(QKeySequence("i"), self) self.shortcut.activated.connect(self.handleInfo) self.shortcut = QShortcut(QKeySequence("s"), self) self.shortcut.activated.connect(self.toggleSlider) self.shortcut = QShortcut(QKeySequence(Qt.Key_Right), self) self.shortcut.activated.connect(self.forwardSlider) self.shortcut = QShortcut(QKeySequence(Qt.Key_Left), self) self.shortcut.activated.connect(self.backSlider) self.shortcut = QShortcut(QKeySequence(Qt.Key_Up), self) self.shortcut.activated.connect(self.volumeUp) self.shortcut = QShortcut(QKeySequence(Qt.Key_Down), self) self.shortcut.activated.connect(self.volumeDown) self.shortcut = QShortcut( QKeySequence(Qt.ShiftModifier + Qt.Key_Right), self) self.shortcut.activated.connect(self.forwardSlider10) self.shortcut = QShortcut(QKeySequence(Qt.ShiftModifier + Qt.Key_Left), self) self.shortcut.activated.connect(self.backSlider10) self.mediaPlayer.setVideoOutput(self.videoWidget) self.mediaPlayer.stateChanged.connect(self.mediaStateChanged) self.mediaPlayer.positionChanged.connect(self.positionChanged) self.mediaPlayer.positionChanged.connect(self.handleLabel) self.mediaPlayer.durationChanged.connect(self.durationChanged) self.mediaPlayer.error.connect(self.handleError) print("QT5 Player started") self.suspend_screensaver() # msg = QMessageBox.information(self, "Qt5Player", "press o to open file") self.loadFilm("/home/brian/Dokumente/Qt5PlayerIntro.m4v") def playFromURL(self): self.mediaPlayer.pause() self.myurl = self.clip.text() self.mediaPlayer.setMedia(QMediaContent(QUrl(self.myurl))) self.playButton.setEnabled(True) self.mediaPlayer.play() self.hideSlider() print(self.myurl) def getYTUrl(self): cmd = "youtube-dl -g -f best " + self.clip.text() print("grabbing YouTube URL") self.process.start(cmd) def dataReady(self): self.myurl = str(self.process.readAll(), encoding='utf8').rstrip() ### self.myurl = self.myurl.partition("\n")[0] print(self.myurl) self.clip.setText(self.myurl) self.playFromURL() def suspend_screensaver(self): 'suspend linux screensaver' proc = subprocess.Popen( 'gsettings set org.gnome.desktop.screensaver idle-activation-enabled false', shell=True) proc.wait() def resume_screensaver(self): 'resume linux screensaver' proc = subprocess.Popen( 'gsettings set org.gnome.desktop.screensaver idle-activation-enabled true', shell=True) proc.wait() def openFile(self): fileName, _ = QFileDialog.getOpenFileName( self, "Open Movie", QDir.homePath() + "/Videos", "Media (*.webm *.mp4 *.ts *.avi *.mpeg *.mpg *.mkv *.VOB *.m4v *.3gp *.mp3 *.m4a *.wav *.ogg *.flac *.m3u *.m3u8)" ) if fileName != '': self.loadFilm(fileName) print("File loaded") def play(self): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.mediaPlayer.pause() else: self.mediaPlayer.play() def mediaStateChanged(self, state): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.playButton.setIcon(self.style().standardIcon( QStyle.SP_MediaPause)) else: self.playButton.setIcon(self.style().standardIcon( QStyle.SP_MediaPlay)) def positionChanged(self, position): self.positionSlider.setValue(position) def durationChanged(self, duration): self.positionSlider.setRange(0, duration) mtime = QTime(0, 0, 0, 0) mtime = mtime.addMSecs(self.mediaPlayer.duration()) self.elbl.setText(mtime.toString()) def setPosition(self, position): self.mediaPlayer.setPosition(position) def handleError(self): self.playButton.setEnabled(False) print("Error: ", self.mediaPlayer.errorString()) def handleQuit(self): self.mediaPlayer.stop() self.resume_screensaver() print("Goodbye ...") app.quit() def contextMenuRequested(self, point): menu = QMenu() actionFile = menu.addAction(QIcon.fromTheme("video-x-generic"), "open File (o)") actionclipboard = menu.addSeparator() actionURL = menu.addAction(QIcon.fromTheme("browser"), "URL from Clipboard (u)") actionclipboard = menu.addSeparator() actionYTurl = menu.addAction(QIcon.fromTheme("youtube"), "URL from YouTube (y)") actionclipboard = menu.addSeparator() actionToggle = menu.addAction(QIcon.fromTheme("next"), "show / hide Slider (s)") actionFull = menu.addAction(QIcon.fromTheme("view-fullscreen"), "Fullscreen (f)") action169 = menu.addAction(QIcon.fromTheme("tv-symbolic"), "16 : 9") action43 = menu.addAction(QIcon.fromTheme("tv-symbolic"), "4 : 3") actionSep = menu.addSeparator() actionInfo = menu.addAction(QIcon.fromTheme("help-about"), "Info (i)") action5 = menu.addSeparator() actionQuit = menu.addAction(QIcon.fromTheme("application-exit"), "Exit (q)") actionFile.triggered.connect(self.openFile) actionQuit.triggered.connect(self.handleQuit) actionFull.triggered.connect(self.handleFullscreen) actionInfo.triggered.connect(self.handleInfo) actionToggle.triggered.connect(self.toggleSlider) actionURL.triggered.connect(self.playFromURL) actionYTurl.triggered.connect(self.getYTUrl) action169.triggered.connect(self.screen169) action43.triggered.connect(self.screen43) menu.exec_(self.mapToGlobal(point)) def wheelEvent(self, event): mwidth = self.frameGeometry().width() mheight = self.frameGeometry().height() mleft = self.frameGeometry().left() mtop = self.frameGeometry().top() mscale = event.angleDelta().y() / 5 if self.widescreen == True: self.setGeometry(mleft, mtop, mwidth + mscale, (mwidth + mscale) / 1.778) else: self.setGeometry(mleft, mtop, mwidth + mscale, (mwidth + mscale) / 1.33) def screen169(self): self.widescreen = True mwidth = self.frameGeometry().width() mheight = self.frameGeometry().height() mleft = self.frameGeometry().left() mtop = self.frameGeometry().top() mratio = 1.778 self.setGeometry(mleft, mtop, mwidth, mwidth / mratio) def screen43(self): self.widescreen = False mwidth = self.frameGeometry().width() mheight = self.frameGeometry().height() mleft = self.frameGeometry().left() mtop = self.frameGeometry().top() mratio = 1.33 self.setGeometry(mleft, mtop, mwidth, mwidth / mratio) def handleFullscreen(self): if self.windowState() & Qt.WindowFullScreen: QApplication.setOverrideCursor(Qt.ArrowCursor) self.showNormal() print("no Fullscreen") else: self.showFullScreen() QApplication.setOverrideCursor(Qt.BlankCursor) print("Fullscreen entered") def handleInfo(self): msg = QMessageBox.about(self, "QT5 Player", self.myinfo) def toggleSlider(self): if self.positionSlider.isVisible(): self.hideSlider() else: self.showSlider() def hideSlider(self): self.playButton.hide() self.lbl.hide() self.positionSlider.hide() self.elbl.hide() mwidth = self.frameGeometry().width() mheight = self.frameGeometry().height() mleft = self.frameGeometry().left() mtop = self.frameGeometry().top() if self.widescreen == True: self.setGeometry(mleft, mtop, mwidth, mwidth / 1.778) else: self.setGeometry(mleft, mtop, mwidth, mwidth / 1.33) def showSlider(self): self.playButton.show() self.lbl.show() self.positionSlider.show() self.elbl.show() mwidth = self.frameGeometry().width() mheight = self.frameGeometry().height() mleft = self.frameGeometry().left() mtop = self.frameGeometry().top() if self.widescreen == True: self.setGeometry(mleft, mtop, mwidth, mwidth / 1.55) else: self.setGeometry(mleft, mtop, mwidth, mwidth / 1.33) def forwardSlider(self): self.mediaPlayer.setPosition(self.mediaPlayer.position() + 1000 * 60) def forwardSlider10(self): self.mediaPlayer.setPosition(self.mediaPlayer.position() + 10000 * 60) def backSlider(self): self.mediaPlayer.setPosition(self.mediaPlayer.position() - 1000 * 60) def backSlider10(self): self.mediaPlayer.setPosition(self.mediaPlayer.position() - 10000 * 60) def volumeUp(self): self.mediaPlayer.setVolume(self.mediaPlayer.volume() + 10) print("Volume: " + str(self.mediaPlayer.volume())) def volumeDown(self): self.mediaPlayer.setVolume(self.mediaPlayer.volume() - 10) print("Volume: " + str(self.mediaPlayer.volume())) def mouseMoveEvent(self, event): if event.buttons() == Qt.LeftButton: self.move(event.globalPos() \ - QPoint(self.frameGeometry().width() / 2, \ self.frameGeometry().height() / 2)) event.accept() def dragEnterEvent(self, event): if event.mimeData().hasUrls(): event.accept() elif event.mimeData().hasText(): event.accept() else: event.ignore() def dropEvent(self, event): if event.mimeData().hasUrls(): url = event.mimeData().urls()[0].toString() print("url = ", url) self.mediaPlayer.stop() self.mediaPlayer.setMedia(QMediaContent(QUrl(url))) self.playButton.setEnabled(True) self.mediaPlayer.play() elif event.mimeData().hasText(): mydrop = event.mimeData().text() ### YouTube url if "youtube" in mydrop: print("is YouTube", mydrop) self.clip.setText(mydrop) self.getYTUrl() else: ### normal url print("generic url = ", mydrop) self.mediaPlayer.setMedia(QMediaContent(QUrl(mydrop))) self.playButton.setEnabled(True) self.mediaPlayer.play() self.hideSlider() def loadFilm(self, f): self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile(f))) self.playButton.setEnabled(True) self.mediaPlayer.play() def printMediaData(self): if self.mediaPlayer.mediaStatus() == 6: if self.mediaPlayer.isMetaDataAvailable(): res = str(self.mediaPlayer.metaData("Resolution")).partition( "PyQt5.QtCore.QSize(")[2].replace(", ", " x ").replace(")", "") print("%s%s" % ("Video Resolution = ", res)) else: print("no metaData available") def openFileAtStart(self, filelist): matching = [s for s in filelist if ".myformat" in s] if len(matching) > 0: self.loadFilm(matching) ##################### update Label ################################## def handleLabel(self): self.lbl.clear() mtime = QTime(0, 0, 0, 0) self.time = mtime.addMSecs(self.mediaPlayer.position()) self.lbl.setText(self.time.toString())
class Music(QtWidgets.QMainWindow): def __init__(self): super().__init__() self.setFixedSize(400,200) self.setWindowTitle("🎧+📚=😊") self.setWindowOpacity(0.8) self.init_ui() self.custom_style() self.play_status = False # 播放状态初始化为否 self.player = QMediaPlayer(self) self.timer = QtCore.QTimer() self.timer.setInterval(1000) self.timer.start() self.timer.timeout.connect(self.check_music_status) # 设置样式 def custom_style(self): self.setStyleSheet(''' #main_widget{ border-radius:5px; background:black; } #play_btn,#pervious_btn,#next_btn{ border:none; } #play_btn:hover,#pervious_btn:hover,#next_btn:hover{ background: #696969; border-radius:5px; cursor:pointer; } ''') self.close_btn.setStyleSheet(''' QPushButton{ background:#F76677; border-radius:5px; } QPushButton:hover{ background:red; }''') self.status_label.setStyleSheet(''' QLabel{ background:#FFD85A; border-radius:5px; } ''') def init_ui(self): # 窗口布局 self.main_widget = QtWidgets.QWidget() self.main_widget.setObjectName("main_widget") self.main_layout = QtWidgets.QGridLayout() self.main_widget.setLayout(self.main_layout) # 标题 半成,接口部分未找到适合的 ''' slogan=requests.get('https://api.xygeng.cn/one').json()['data']['content'] self.title_lable = QtWidgets.QLabel(slogan) self.title_lable.setFont(font) ''' self.title_lable = QtWidgets.QLabel('🌥WindPlayer') self.title_lable.setStyleSheet(''' QLabel{ color:"gray"; } ''') self.title_lable.setFont(font) self.title_lable.setAlignment(QtCore.Qt.AlignCenter) # 关闭按钮 self.close_btn = QtWidgets.QPushButton("") # 关闭按钮 self.close_btn.clicked.connect(self.close_btn_event) self.close_btn.setFixedSize(15,15) # 音乐状态按钮 self.status_label = QtWidgets.QLabel("") # self.swith_btn.clicked.connect(self.swith_background) #此处还未完成 Darkmode 和 LightMode 的切换 self.status_label.setFixedSize(15,15) # 播放按钮 play_icon = qta.icon("fa.play-circle-o",) self.play_btn = QtWidgets.QPushButton(play_icon,"") self.play_btn.setIconSize(QtCore.QSize(80, 80)) self.play_btn.setFixedSize(82,82) self.play_btn.setObjectName("play_btn") self.play_btn.clicked.connect(self.play_music) self.play_btn.setStyleSheet(''' QPushButton{ background:black; border-radius:5px; } QPushButton:hover{ background: #696969; }''') # 下一首按钮 next_icon = qta.icon("fa.chevron-right") self.next_btn = QtWidgets.QPushButton(next_icon,"") self.next_btn.setIconSize(QtCore.QSize(80,80)) self.next_btn.setFixedSize(82,82) self.next_btn.setObjectName("next_btn") self.next_btn.clicked.connect(self.next_music) self.next_btn.setStyleSheet(''' QPushButton{ background:black; border-radius:5px; } QPushButton:hover{ background: #696969; }''') # 进度条 self.process_bar = QtWidgets.QProgressBar() self.process_value = 0 self.process_bar.setValue(self.process_value) self.process_bar.setFixedHeight(5) self.process_bar.setTextVisible(False) self.process_bar.setStyleSheet('''QProgressBar { border: 2px solid grey; border-radius: 5px; background-color: #FFFFFF;}QProgressBar::chunk { background-color: #05B8CC; width: 28px;}QProgressBar { border: 2px solid grey; border-radius: 5px; text-align: center;} ''') self.main_layout.addWidget(self.close_btn,0,0,1,1) self.main_layout.addWidget(self.title_lable,0,1,1,1) self.main_layout.addWidget(self.status_label,1,0,1,1) self.main_layout.addWidget(self.play_btn, 1, 1, 1, 1) self.main_layout.addWidget(self.next_btn, 1, 2, 1, 1) self.main_layout.addWidget(self.process_bar,2,0,1,3) self.setCentralWidget(self.main_widget) self.setWindowFlag(QtCore.Qt.FramelessWindowHint) # 隐藏边框 # 关闭程序 def close_btn_event(self): self.close() # 夜间模式切换 (未完成 ) def swich_background(self): self.main_widget.setStyleSheet(''' QWidget{ "background-color: black"} ''') # 鼠标长按事件 def mousePressEvent(self, event): if event.button() == QtCore.Qt.LeftButton: self.m_drag = True self.m_DragPosition = event.globalPos() - self.pos() event.accept() self.setCursor(QtGui.QCursor(QtCore.Qt.OpenHandCursor)) # 鼠标移动事件 def mouseMoveEvent(self, QMouseEvent): if QtCore.Qt.LeftButton and self.m_drag: self.move(QMouseEvent.globalPos() - self.m_DragPosition) QMouseEvent.accept() # 鼠标释放事件 def mouseReleaseEvent(self, QMouseEvent): self.m_drag = False self.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor)) # 播放音乐 def play_music(self): try: # 播放音乐 if self.play_status is False: self.play_status = True # 设置播放状态为是 self.play_btn.setIcon(qta.icon("fa.pause-circle")) # 设置播放图标 player_status = self.player.mediaStatus() # 获取播放器状态 # print("当前播放状态:",player_status) if player_status == 6: # 设置状态标签为绿色 self.status_label.setStyleSheet('''QLabel{background:#72EA72;border-radius:5px;}''') self.player.play() else: self.next_music() # 暂停音乐 else: # 设置状态为蓝色 self.status_label.setStyleSheet('''QLabel{background:#0099CC;border-radius:5px;}''') self.play_status = False self.play_btn.setIcon(qta.icon("fa.play-circle")) self.player.pause() except Exception as e: print(repr(e)) # 下一首音乐 def next_music(self): try: # 设置状态为黄色 self.status_label.setStyleSheet(''' QLabel{ background:#FFBF00; border-radius:5px; } ''') self.play_status = True # 设置播放状态为是 self.play_btn.setIcon(qta.icon("fa.pause-circle")) # 修改播放图标 self.process_value = 0 # 重置进度值 # 获取网络歌曲 self.get_music_thread = GetMusicThread() self.get_music_thread.finished_signal.connect(self.init_player) self.get_music_thread.start() except Exception as e: print(traceback.print_exc()) # 设置播放器 def init_player(self,url): # print("获取到音乐链接:",url) content = QMediaContent(QtCore.QUrl(url)) self.player.setMedia(content) self.player.setVolume(50) self.player.play() self.duration = self.player.duration() # 音乐的时长 # 设置状态为绿色 self.status_label.setStyleSheet(''' QLabel{ background:#72EA72; border-radius:5px; } ''') # 进度条计时器 self.process_timer = QtCore.QTimer() self.process_timer.setInterval(1000) self.process_timer.start() self.process_timer.timeout.connect(self.process_timer_status) # 定时器 def check_music_status(self): player_status = self.player.mediaStatus() player_duration = self.player.duration() # print("音乐时间:",player_duration) # print("当前播放器状态",player_status) if player_status == 7: self.next_music() if player_duration > 0: self.duration = player_duration # 进度条定时器 def process_timer_status(self): try: if self.play_status is True: self.process_value +=float(100 / (self.duration/1000)) #print("当前进度:",self.process_value) self.process_bar.setValue(self.process_value) except Exception as e: print('')
class VideoPlayer(QWidget): def __init__(self, aPath, parent=None): super(VideoPlayer, self).__init__(parent) #self.setAttribute(Qt.WA_NoSystemBackground, True) self.colorDialog = None self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.mediaPlayer.setVolume(80) self.videoWidget = QVideoWidget(self) self.lbl = QLineEdit('00:00:00') self.lbl.setReadOnly(True) self.lbl.setEnabled(False) self.lbl.setFixedWidth(60) self.lbl.setUpdatesEnabled(True) #self.lbl.setStyleSheet(stylesheet(self)) self.elbl = QLineEdit('00:00:00') self.elbl.setReadOnly(True) self.elbl.setEnabled(False) self.elbl.setFixedWidth(60) self.elbl.setUpdatesEnabled(True) #self.elbl.setStyleSheet(stylesheet(self)) self.playButton = QPushButton() self.playButton.setEnabled(False) self.playButton.setFixedWidth(32) #self.playButton.setStyleSheet("background-color: black") self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay)) self.playButton.clicked.connect(self.play) ### pointA button self.apointButton = QPushButton() self.apointButton.setEnabled(False) self.apointButton.setFixedWidth(32) #self.apointButton.setStyleSheet("background-color: black") self.apointButton.setIcon(self.style().standardIcon( QStyle.SP_MediaSeekForward)) self.apointButton.clicked.connect(self.setPointA) ### pointB button self.bpointButton = QPushButton() self.bpointButton.setEnabled(False) self.bpointButton.setFixedWidth(32) #self.bpointButton.setStyleSheet("background-color: black") self.bpointButton.setIcon(self.style().standardIcon( QStyle.SP_MediaSeekBackward)) self.bpointButton.clicked.connect(self.setPointB) ### cut button self.cutButton = QPushButton() self.cutButton.setEnabled(False) self.cutButton.setFixedWidth(32) self.cutButton.setIcon(self.style().standardIcon( QStyle.SP_DriveFDIcon)) self.cutButton.clicked.connect(self.cut) self.positionSlider = QSlider(Qt.Horizontal, self) self.positionSlider.setStyleSheet(stylesheet(self)) self.positionSlider.setRange(0, 100) self.positionSlider.sliderMoved.connect(self.setPosition) self.positionSlider.sliderMoved.connect(self.handle_label) self.positionSlider.setSingleStep(2) self.positionSlider.setPageStep(20) #self.positionSlider.setAttribute(Qt.WA_NoSystemBackground, True) controlLayout = QHBoxLayout() controlLayout.setContentsMargins(5, 0, 5, 0) controlLayout.addWidget(self.playButton) controlLayout.addWidget(self.apointButton) controlLayout.addWidget(self.bpointButton) controlLayout.addWidget(self.cutButton) controlLayout.addWidget(self.lbl) controlLayout.addWidget(self.positionSlider) controlLayout.addWidget(self.elbl) layout0 = QVBoxLayout() layout0.setContentsMargins(0, 0, 0, 0) layout0.addWidget(self.videoWidget) layout0.addLayout(controlLayout) self.setLayout(layout0) self.widescreen = True self.setAcceptDrops(True) self.setWindowTitle("QT5 Player") #self.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint) self.setGeometry(300, 200, 400, 290) self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.customContextMenuRequested[QtCore.QPoint].connect( self.contextMenuRequested) #self.hideSlider() self.show() #self.playFromURL() ### shortcuts ### self.shortcut = QShortcut(QKeySequence('q'), self) self.shortcut.activated.connect(self.handleQuit) self.shortcut = QShortcut(QKeySequence('o'), self) self.shortcut.activated.connect(self.openFile) self.shortcut = QShortcut(QKeySequence(' '), self) self.shortcut.activated.connect(self.play) self.shortcut = QShortcut(QKeySequence('s'), self) self.shortcut.activated.connect(self.toggleSlider) self.shortcut = QShortcut(QKeySequence('v'), self) self.shortcut.activated.connect(self.setPointA) self.shortcut = QShortcut(QKeySequence('b'), self) self.shortcut.activated.connect(self.setPointB) self.shortcut = QShortcut(QKeySequence(Qt.Key_Right), self) self.shortcut.activated.connect(self.forwardSlider) self.shortcut = QShortcut(QKeySequence(Qt.Key_Left), self) self.shortcut.activated.connect(self.backSlider) self.shortcut = QShortcut(QKeySequence(Qt.Key_Up), self) self.shortcut.activated.connect(self.volumeUp) self.shortcut = QShortcut(QKeySequence(Qt.Key_Down), self) self.shortcut.activated.connect(self.volumeDown) self.shortcut = QShortcut( QKeySequence(Qt.ShiftModifier + Qt.Key_Right), self) self.shortcut.activated.connect(self.forwardSlider10) self.shortcut = QShortcut(QKeySequence(Qt.ShiftModifier + Qt.Key_Left), self) self.shortcut.activated.connect(self.backSlider10) self.mediaPlayer.setVideoOutput(self.videoWidget) self.mediaPlayer.stateChanged.connect(self.mediaStateChanged) self.mediaPlayer.positionChanged.connect(self.positionChanged) self.mediaPlayer.positionChanged.connect(self.handle_label) self.mediaPlayer.durationChanged.connect(self.durationChanged) self.mediaPlayer.error.connect(self.handleError) self.apoint = 0 self.bpoint = 0 self.inputfile = pathlib.Path() # self.outputfile = pathlib.Path() def openFile(self): fileName, _ = QFileDialog.getOpenFileName( self, 'Open Movie', QDir.homePath() + '/Desktop', 'Videos (*.mp4 *.ts *.avi *.mpeg *.mpg *.mkv *.VOB *.m4v)') if fileName != '': self.load_film(fileName) print("File loaded") print(fileName) self.inputfile = pathlib.Path(fileName) def getclipFileName(self): clipFileName = QFileDialog.getSaveFileName( self, 'Save Clip', QDir.homePath() + '/Desktop', 'all files(*.*)') return clipFileName #def playFromURL(self): def play(self): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.mediaPlayer.pause() else: self.mediaPlayer.play() def mediaStateChanged(self, state): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.playButton.setIcon(self.style().standardIcon( QStyle.SP_MediaPause)) else: self.playButton.setIcon(self.style().standardIcon( QStyle.SP_MediaPlay)) def positionChanged(self, position): self.positionSlider.setValue(position) def durationChanged(self, duration): self.positionSlider.setRange(0, duration) mtime = QTime(0, 0, 0, 0) mtime = mtime.addMSecs(self.mediaPlayer.duration()) self.elbl.setText(mtime.toString()) def setPosition(self, position): self.mediaPlayer.setPosition(position) # cut point A function def setPointA(self): self.apoint = self.time.toString() print('A Point ' + self.apoint) # cut point B function def setPointB(self): self.play() self.bpoint = self.time.toString() print('B Point ' + self.bpoint) # cut def cut(self): print("Input: ", self.inputfile.resolve()) length = self.lengthCalculation(self.apoint, self.bpoint) output_file = os.path.splitext(str( self.inputfile.resolve()))[0] + '__' + re.sub( ':', '_', self.apoint) + '__' + re.sub( ':', '_', self.bpoint ) + self.inputfile.suffix # no ':' allowed in a windows path. print("Output:", output_file) command = "ffmpeg -i " + "\"" + str( self.inputfile.resolve() ) + "\"" + " -ss " + self.apoint + " -t " + length + " -c:v copy -c:a copy " + "\"" + output_file + "\"" print("Executing:\n", command, "\n") run(command, shell=True) # cut length calculation def twodigi(self, str0): if len(str0) == 1: str0 = '0' + str0 return str0 def lengthCalculation(self, start, end): start_s = int(start[:2]) * 3600 + int(start[3:5]) * 60 + int(start[6:]) # print(start_s) end_s = int(end[:2]) * 3600 + int(end[3:5]) * 60 + int(end[6:]) # print(end_s) length_s = end_s - start_s # print(length_s) hr = self.twodigi(str(length_s // 3600)) mn = self.twodigi(str((length_s % 3600) // 60)) sc = self.twodigi(str(length_s % 60)) length = hr + ':' + mn + ':' + sc print(length) return length def handleError(self): self.playButton.setEnabled(False) self.apointButton.setEnabled(False) self.bpointButton.setEnabled(False) self.cutButton.setEnabled(False) print("Error: " + self.mediaPlayer.errorString()) def handleQuit(self): self.mediaPlayer.stop() print('Quit.') app.quit() def contextMenuRequested(self, point): menu = QtWidgets.QMenu() actionFile = menu.addAction('Open File (o)') actionFile.triggered.connect(self.openFile) actionToggle = menu.addAction('show / hide Slider (s)') actionToggle.triggered.connect(self.toggleSlider) action169 = menu.addAction('16 : 9') action169.triggered.connect(self.screen169) action43 = menu.addAction('4 : 3') action43.triggered.connect(self.screen43) actionQuit = menu.addAction('Exit (q)') actionQuit.triggered.connect(self.handleQuit) menu.exec_(self.mapToGlobal(point)) def wheelEvent(self, event): mwidth = self.frameGeometry().width() #mheight = self.frameGeometry().height() mleft = self.frameGeometry().left() mtop = self.frameGeometry().top() mscale = event.angleDelta().y() / 5 if self.widescreen == True: self.setGeometry(mleft, mtop, mwidth + mscale, (mwidth + mscale) / 1.778) else: self.setGeometry(mleft, mtop, mwidth + mscale, (mwidth + mscale) / 1.33) def screen169(self): self.widescreen = True mwidth = self.frameGeometry().width() #mheight = self.frameGeometry().height() mleft = self.frameGeometry().left() mtop = self.frameGeometry().top() mratio = 1.778 self.setGeometry(mleft, mtop, mwidth, mwidth / mratio) def screen43(self): self.widescreen = False mwidth = self.frameGeometry().width() #mheight = self.frameGeometry().height() mleft = self.frameGeometry().left() mtop = self.frameGeometry().top() mratio = 1.33 self.setGeometry(mleft, mtop, mwidth, mwidth / mratio) def handleFullscreen(self): pass def handleInfo(self): pass def toggleSlider(self): if self.positionSlider.isVisible(): self.hideSlider() else: self.showSlider() def hideSlider(self): self.playButton.hide() self.lbl.hide() self.positionSlider.hide() self.elbl.hide() mwidth = self.frameGeometry().width() mleft = self.frameGeometry().left() mtop = self.frameGeometry().top() if self.widescreen == True: self.setGeometry(mleft, mtop, mwidth, mwidth / 1.778) else: self.setGeometry(mleft, mtop, mwidth, mwidth / 1.33) def showSlider(self): self.playButton.show() self.lbl.show() self.positionSlider.show() self.elbl.show() mwidth = self.frameGeometry().width() mleft = self.frameGeometry().left() mtop = self.frameGeometry().top() self.positionSlider.setFocus() if self.widescreen == True: self.setGeometry(mleft, mtop, mwidth, mwidth / 1.55) else: self.setGeometry(mleft, mtop, mwidth, mwidth / 1.33) def forwardSlider(self): self.mediaPlayer.setPosition(self.mediaPlayer.position() + 100 * 60) def forwardSlider10(self): self.mediaPlayer.setPosition(self.mediaPlayer.position() + 250 * 60) def backSlider(self): self.mediaPlayer.setPosition(self.mediaPlayer.position() - 100 * 60) def backSlider10(self): self.mediaPlayer.setPosition(self.mediaPlayer.position() - 250 * 60) def volumeUp(self): self.mediaPlayer.setVolume(self.mediaPlayer.volume() + 10) def volumeDown(self): self.mediaPlayer.setVolume(self.mediaPlayer.volume() - 10) ''' def mouseMoveEvent(self, event): if event.buttons() == Qt.LeftButton: #self.move(event.globalPos() - QPoint(self.frameGeometry().width() / 2, self.frameGeometry().height() / 2)) self.move(event.globalPos() - QPoint(self.geometry().left(),self.geometry().top())) event.accept() ''' def dragEnterEvent(self, event): if event.mimeData().hasUrls(): event.accept() elif event.mimeData().hasFormat('text/plain'): event.accept() else: event.ignore() def dropEvent(self, event): if event.mimeData().hasUrls(): f = str(event.mimeData().urls()[0].toLocalFile()) self.load_film(f) self.inputfile = pathlib.Path(f) elif event.mimeData().hasText(): f = str(event.mimeData().text()) self.mediaPlayer.setMedia(QMediaContent(QUrl(f))) self.inputfile = pathlib.Path(f) self.mediaPlayer.play() def load_film(self, f): self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile(f))) self.playButton.setEnabled(True) self.apointButton.setEnabled(True) self.bpointButton.setEnabled(True) self.cutButton.setEnabled(True) self.mediaPlayer.play() def open_file_at_start(self, filelist): matching = [s for s in filelist if '.myformat' in s] if len(matching) > 0: self.load_film(matching) def handle_label(self): self.lbl.clear() mtime = QTime(0, 0, 0, 0) self.time = mtime.addMSecs(self.mediaPlayer.position()) self.lbl.setText(self.time.toString())
class 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 Player(QMediaPlayer): def __init__(self, parent=None): super(Player, self).__init__(parent) self.parent = parent self.player = QMediaPlayer() self.queueList = QMediaPlaylist() self.player.setPlaylist(self.queueList) self.queueData = [] self.position = 0 self.volume = 100 self.player.mediaStatusChanged.connect(self.qmp_mediaStatusChanged) self.player.positionChanged.connect(self.qmp_positionChanged) self.player.durationChanged.connect(self.durationChanged) self.queueList.currentIndexChanged.connect(self.playlistPosChanged) def add(self, data): """Add track to the queue""" queueData = { 'pc_title': data['pc_title'], 'title': data['title'], 'url': data['url'], 'date': data['date_format'], 'description': data['description'] } self.queueData.append(queueData) self.queueList.addMedia(QMediaContent(QUrl(data['url']))) def playPause(self): icon = QIcon.fromTheme("media-playback-pause") if self.player.state() == QMediaPlayer.StoppedState: if self.player.mediaStatus() == QMediaPlayer.NoMedia: if self.queueList.mediaCount() != 0: self.player.play() elif self.player.mediaStatus() == QMediaPlayer.LoadedMedia: self.queueList.setCurrentIndex(self.position) self.player.play() elif self.player.mediaStatus() == QMediaPlayer.BufferedMedia: self.player.play() elif self.player.state() == QMediaPlayer.PlayingState: icon = QIcon.fromTheme("media-playback-start") self.player.pause() elif self.player.state() == QMediaPlayer.PausedState: self.player.play() self.parent.playBtn.setIcon(icon) def startPlay(self): data = self.queueData[0] self.queueList.setCurrentIndex(0) self.parent.curPCLabel.setText(data['pc_title']) self.parent.curTrackName.setText(data['title']) self.player.play() icon = QIcon.fromTheme("media-playback-pause") self.parent.playBtn.setIcon(icon) def stop(self): self.player.stop() icon = QIcon.fromTheme("media-playback-start") self.parent.playBtn.setIcon(icon) def setPosition(self, pos): self.player.setPosition(pos) def durationChanged(self, duration): total_time = '0:00:00' duration = self.player.duration() total_time = ms_to_time(duration) self.parent.timeSlider.setMaximum(duration) self.currentTrackDuration = duration self.parent.totalTimeLabel.setText(total_time) def qmp_mediaStatusChanged(self, status): icon = QIcon.fromTheme("media-playback-pause") if self.player.state() == QMediaPlayer.StoppedState: icon = QIcon.fromTheme("media-playback-start") elif self.player.state() == QMediaPlayer.PausedState: icon = QIcon.fromTheme("media-playback-start") self.parent.playBtn.setIcon(icon) def qmp_positionChanged(self, position, senderType=False): self.currentTime = position current_time = '0:00:00' if position != -1: current_time = ms_to_time(position) self.parent.timeLabel.setText(current_time) self.parent.timeSlider.blockSignals(True) self.parent.timeSlider.setValue(position) self.parent.timeSlider.blockSignals(False) def playlistPosChanged(self): pos = self.queueList.currentIndex() data = self.queueData[pos] self.parent.curPCLabel.setText(data['pc_title']) self.parent.curTrackName.setText(data['title']) windowTitle = '{0} - {1}'.format(data['pc_title'], data['title']) self.parent.setWindowTitle(windowTitle) if self.queueList.mediaCount() > 1: if pos < self.queueList.mediaCount() - 1: self.parent.queueNextBtn.setEnabled(True) else: self.parent.queueNextBtn.setEnabled(False) if pos > 0: self.parent.queuePrevBtn.setEnabled(True) else: self.parent.queuePrevBtn.setEnabled(False) if pos < self.queueList.mediaCount(): prevPos = 0 if self.position < pos: prevPos = pos - 1 else: prevPos = pos + 1 prevItem = self.parent.queueList.item(prevPos) prevWidget = self.parent.queueList.itemWidget(prevItem) if prevItem: prevWidget.statusIcon.setPixmap(QPixmap()) self.position = pos item = self.parent.queueList.item(pos) widget = self.parent.queueList.itemWidget(item) if widget: icon = QIcon.fromTheme("media-playback-start") widget.statusIcon.setPixmap(icon.pixmap(16, 16)) def setVolume(self, volume): self.player.setVolume(volume) def rev10Secs(self): position = self.player.position() new_pos = position - 10000 self.player.setPosition(new_pos) def for10Secs(self): position = self.player.position() new_pos = position + 10000 self.player.setPosition(new_pos) def delete(self, position): """ Delete the track and her data from position""" self.queueData.pop(position) self.queueList.removeMedia(position) if (position == self.position): self.playlistPosChanged()
class Window(QMainWindow): def __init__(self): super().__init__() self.title = "Python Annotator for VideoS" # self.top = 100 # self.left = 100 # self.width = 300 # self.height = 400 # self.setWindowState = "Qt.WindowMaximized" iconName = "home.png" self.InitWindow() def InitWindow(self): self.setWindowTitle(self.title) # self.setWindowIcon(QtGui.QIcon(iconName)) self.setWindowState(QtCore.Qt.WindowMaximized) self.UiComponents() self.show() def UiComponents(self): self.rowNo = 1 self.colNo = 0 self.fName = "" self.fName2 = "" self.fileNameExist = "" self.dropDownName = "" self.model = QStandardItemModel() self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.tableWidget = QTableWidget() self.tableWidget.cellClicked.connect(self.checkTableFrame) self.videoWidget = QVideoWidget() self.frameID=0 self.insertBaseRow() openButton = QPushButton("Open...") openButton.clicked.connect(self.openFile) self.playButton = QPushButton() self.playButton.setEnabled(False) self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay)) self.playButton.clicked.connect(self.play) self.lbl = QLabel('00:00:00') self.lbl.setFixedWidth(60) self.lbl.setUpdatesEnabled(True) # self.lbl.setStyleSheet(stylesheet(self)) self.elbl = QLabel('00:00:00') self.elbl.setFixedWidth(60) self.elbl.setUpdatesEnabled(True) # self.elbl.setStyleSheet(stylesheet(self)) self.nextButton = QPushButton("-->") self.nextButton.clicked.connect(self.next) self.delButton = QPushButton("Delete") self.delButton.clicked.connect(self.delete) self.exportButton = QPushButton("Export") self.exportButton.clicked.connect(self.export) self.importButton = QPushButton("Import") self.importButton.clicked.connect(self.importCSV) # self.ctr = QLineEdit() # self.ctr.setPlaceholderText("Extra") self.startTime = QLineEdit() self.startTime.setPlaceholderText("Select Start Time") self.endTime = QLineEdit() self.endTime.setPlaceholderText("Select End Time") self.iLabel = QComboBox(self) self.iLabel.addItem("1. Eye Contact") self.iLabel.addItem("2. Pointing") self.iLabel.addItem("3. Response to Names") self.iLabel.addItem("4. Following Pointing") self.iLabel.addItem("5. Babbling") self.iLabel.addItem("6. Question-Answering") self.iLabel.addItem("7. Showing") self.iLabel.addItem("8. Following Instructions") self.iLabel.activated[str].connect(self.style_choice) # self.iLabel = QLineEdit() # self.iLabel.setPlaceholderText("Label") self.positionSlider = QSlider(Qt.Horizontal) self.positionSlider.setRange(0, 100) self.positionSlider.sliderMoved.connect(self.setPosition) self.positionSlider.sliderMoved.connect(self.handleLabel) self.positionSlider.setSingleStep(2) self.positionSlider.setPageStep(20) self.positionSlider.setAttribute(Qt.WA_TranslucentBackground, True) self.errorLabel = QLabel() self.errorLabel.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum) # Main plotBox plotBox = QHBoxLayout() controlLayout = QHBoxLayout() # controlLayout.setContentsMargins(0, 0, 0, 0) controlLayout.addWidget(openButton) controlLayout.addWidget(self.playButton) controlLayout.addWidget(self.lbl) controlLayout.addWidget(self.positionSlider) controlLayout.addWidget(self.elbl) wid = QWidget(self) self.setCentralWidget(wid) # Left Layout{ # layout.addWidget(self.videoWidget) layout = QVBoxLayout() layout.addWidget(self.videoWidget, 3) # layout.addLayout(self.grid_root) layout.addLayout(controlLayout) layout.addWidget(self.errorLabel) plotBox.addLayout(layout, 3) # } # Right Layout { inputFields = QHBoxLayout() inputFields.addWidget(self.startTime) inputFields.addWidget(self.endTime) inputFields.addWidget(self.iLabel) # inputFields.addWidget(self.ctr) feats = QHBoxLayout() feats.addWidget(self.nextButton) feats.addWidget(self.delButton) feats.addWidget(self.exportButton) feats.addWidget(self.importButton) layout2 = QVBoxLayout() layout2.addWidget(self.tableWidget) layout2.addLayout(inputFields, 1) layout2.addLayout(feats, 2) # layout2.addWidget(self.nextButton) # } plotBox.addLayout(layout2, 1) # self.setLayout(layout) wid.setLayout(plotBox) self.shortcut = QShortcut(QKeySequence("["), self) self.shortcut.activated.connect(self.addStartTime) self.shortcut = QShortcut(QKeySequence("]"), self) self.shortcut.activated.connect(self.addEndTime) self.shortcut = QShortcut(QKeySequence("L"), self) self.shortcut.activated.connect(self.openFile) self.shortcut = QShortcut(QKeySequence("C"), self) self.shortcut.activated.connect(self.clearTable) self.shortcut = QShortcut(QKeySequence(Qt.Key_Right), self) self.shortcut.activated.connect(self.forwardSlider) self.shortcut = QShortcut(QKeySequence(Qt.Key_Left), self) self.shortcut.activated.connect(self.backSlider) self.shortcut = QShortcut(QKeySequence(Qt.Key_Up), self) self.shortcut.activated.connect(self.volumeUp) self.shortcut = QShortcut(QKeySequence(Qt.Key_Down), self) self.shortcut.activated.connect(self.volumeDown) self.shortcut = QShortcut(QKeySequence(Qt.ShiftModifier + Qt.Key_Right) , self) self.shortcut.activated.connect(self.forwardSlider10) self.shortcut = QShortcut(QKeySequence(Qt.ShiftModifier + Qt.Key_Left) , self) self.shortcut.activated.connect(self.backSlider10) self.mediaPlayer.setVideoOutput(self.videoWidget) self.mediaPlayer.stateChanged.connect(self.mediaStateChanged) self.mediaPlayer.positionChanged.connect(self.positionChanged) self.mediaPlayer.positionChanged.connect(self.handleLabel) self.mediaPlayer.durationChanged.connect(self.durationChanged) self.mediaPlayer.error.connect(self.handleError) def openFile(self): fileName, _ = QFileDialog.getOpenFileName(self, "Open Movie", QDir.homePath()) if fileName != '': self.fileNameExist = fileName self.mediaPlayer.setMedia( QMediaContent(QUrl.fromLocalFile(fileName))) self.playButton.setEnabled(True) self.videopath = QUrl.fromLocalFile(fileName) self.errorLabel.setText(fileName) self.errorLabel.setStyleSheet('color: black') def play(self): # self.is_playing_video = not self.is_playing_video if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.mediaPlayer.pause() else: self.mediaPlayer.play() # self._play_video() # self.errorLabel.setText("Start: " + " -- " + " End:") def _play_video(self): if self.is_playing_video and self.video_fps: frame_idx = min(self.render_frame_idx+1, self.frame_count) print(frame_idx) if frame_idx == self.frame_count: self.on_play_video_clicked() else: self.target_frame_idx = frame_idx def style_choice(self, text): self.dropDownName = text QApplication.setStyle(QStyleFactory.create(text)) def addStartTime(self): self.startTime.setText(self.lbl.text()) def addEndTime(self): self.endTime.setText(self.lbl.text()) def next(self): self.tableWidget.setItem(self.rowNo, self.colNo, QTableWidgetItem(self.startTime.text())) self.colNo += 1 self.tableWidget.setItem(self.rowNo, self.colNo, QTableWidgetItem(self.endTime.text())) self.colNo += 1 self.tableWidget.setItem(self.rowNo, self.colNo, QTableWidgetItem(str(self.iLabel.currentIndex()+1))) self.colNo += 1 self.tableWidget.setItem(self.rowNo, self.colNo, QTableWidgetItem(self.iLabel.currentText().split(' ')[1])) self.colNo = 0 self.rowNo += 1 # print(self.ctr.text(), self.startTime.text(), self.iLabel.text(), self.rowNo, self.colNo) # print(self.iLabel.currentIndex()) def delete(self): # print("delete") index_list = [] for model_index in self.tableWidget.selectionModel().selectedRows(): index = QtCore.QPersistentModelIndex(model_index) index_list.append(index) self.rowNo = self.rowNo - len(index_list) for index in index_list: self.tableWidget.removeRow(index.row()) def clearTable(self): while self.tableWidget.rowCount() > 0: self.tableWidget.removeRow(0) self.insertBaseRow() print("Clearing") def export(self): self.fName = ((self.fileNameExist.rsplit('/', 1)[1]).rsplit('.',1))[0] path, _ = QFileDialog.getSaveFileName(self, 'Save File', QDir.homePath() + "/"+self.fName+".csv", "CSV Files(*.csv *.txt)") if path: with open(path, 'w') as stream: print("saving", path) writer = csv.writer(stream) # writer = csv.writer(stream, delimiter=self.delimit) for row in range(self.tableWidget.rowCount()): rowdata = [] for column in range(self.tableWidget.columnCount()): item = self.tableWidget.item(row, column) if item is not None and item is not "": rowdata.append(item.text()) else: break writer.writerow(rowdata) # self.isChanged = False # self.setCurrentFile(path) def importCSV(self): # if fName2 != "": # self.fName2 = ((self.fileNameExist.rsplit('/', 1)[1]).rsplit('.',1))[0] # path, _ = QFileDialog.getSaveFileName(self, 'Save File', QDir.homePath() + "/"+self.fName2+".csv", "CSV Files(*.csv *.txt)") # else: self.clearTable() path, _ = QFileDialog.getOpenFileName(self, 'Save File', QDir.homePath() , "CSV Files(*.csv *.txt)") print(path) if path: with open(path, 'r') as stream: print("loading", path) reader = csv.reader(stream) # reader = csv.reader(stream, delimiter=';', quoting=csv.QUOTE_ALL) # reader = csv.reader(stream, delimiter=';', quoting=csv.QUOTE_ALL) # for row in reader: for i, row in enumerate(reader): if i == 0: continue else: if(len(row) == 4): st, et, li, ln = row self.tableWidget.setItem(self.rowNo, self.colNo, QTableWidgetItem(st)) self.colNo += 1 self.tableWidget.setItem(self.rowNo, self.colNo, QTableWidgetItem(et)) self.colNo += 1 self.tableWidget.setItem(self.rowNo, self.colNo, QTableWidgetItem(str(li))) self.colNo += 1 self.tableWidget.setItem(self.rowNo, self.colNo, QTableWidgetItem(ln)) self.rowNo += 1 self.colNo = 0 def insertBaseRow(self): self.tableWidget.setColumnCount(4) #, Start Time, End Time, TimeStamp self.tableWidget.setRowCount(50) self.rowNo = 1 self.colNo = 0 self.tableWidget.setItem(0, 0, QTableWidgetItem("Start Time")) self.tableWidget.setItem(0, 1, QTableWidgetItem("End Time")) self.tableWidget.setItem(0, 2, QTableWidgetItem("Label Index")) self.tableWidget.setItem(0, 3, QTableWidgetItem("Label Name")) def checkTableFrame(self, row, column): if ((row > 0) and (column < 2)): # print("Row %d and Column %d was clicked" % (row, column)) item = self.tableWidget.item(row, column) if (item != (None and "")): try: itemFrame = item.text() itemFrame = itemFrame.split(":") frameTime = int(itemFrame[2]) + int(itemFrame[1])*60 + int(itemFrame[0])*3600 elblFrames = self.elbl.text().split(":") elblFrameTime = int(elblFrames[2]) + int(elblFrames[1])*60 + int(elblFrames[0])*3600 # print("Elbl FT ", str(elblFrameTime)) # print("FT ", str(frameTime)) # print(frameTime) self.mediaPlayer.setPosition(frameTime*1000+1*60) except: self.errorLabel.setText("Some Video Error - Please Recheck Video Imported!") self.errorLabel.setStyleSheet('color: red') def mediaStateChanged(self, state): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.playButton.setIcon( self.style().standardIcon(QStyle.SP_MediaPause)) else: self.playButton.setIcon( self.style().standardIcon(QStyle.SP_MediaPlay)) def positionChanged(self, position): self.positionSlider.setValue(position) def durationChanged(self, duration): self.positionSlider.setRange(0, duration) mtime = QTime(0,0,0,0) mtime = mtime.addMSecs(self.mediaPlayer.duration()) self.elbl.setText(mtime.toString()) def setPosition(self, position): self.mediaPlayer.setPosition(position) def handleError(self): self.playButton.setEnabled(False) self.errorLabel.setText("Error: " + self.mediaPlayer.errorString()) self.errorLabel.setStyleSheet('color: red') def forwardSlider(self): self.mediaPlayer.setPosition(self.mediaPlayer.position() + 1*60) def forwardSlider10(self): self.mediaPlayer.setPosition(self.mediaPlayer.position() + 1000*60) def backSlider(self): self.mediaPlayer.setPosition(self.mediaPlayer.position() - 1*60) def backSlider10(self): self.mediaPlayer.setPosition(self.mediaPlayer.position() - 1000*60) def volumeUp(self): self.mediaPlayer.setVolume(self.mediaPlayer.volume() + 10) print("Volume: " + str(self.mediaPlayer.volume())) def volumeDown(self): self.mediaPlayer.setVolume(self.mediaPlayer.volume() - 10) print("Volume: " + str(self.mediaPlayer.volume())) # def mouseMoveEvent(self, event): # if event.buttons() == Qt.LeftButton: # self.move(event.globalPos() \- QPoint(self.frameGeometry().width() / 2, \ # self.frameGeometry().height() / 2)) # event.accept() def dragEnterEvent(self, event): if event.mimeData().hasUrls(): event.accept() else: event.ignore() ##################### update Label ################################## def handleLabel(self): self.lbl.clear() mtime = QTime(0,0,0,0) self.time = mtime.addMSecs(self.mediaPlayer.position()) self.lbl.setText(self.time.toString()) def dropEvent(self, event): f = str(event.mimeData().urls()[0].toLocalFile()) self.loadFilm(f) def clickFile(self): print("File Clicked") def clickExit(self): sys.exit()
class MyWin(QtWidgets.QMainWindow): lbs = [] rbs = [[''] * 10] * 15 # emply list 15x10 bgrs = [] labels = [] variants = [] correct = [] value = [] tp = [] picName = [] lblPic = [] logStr = '' triggeredNum = 0 minNum = 0 name1 = '' group1 = '' timeRes = 0 timesListening = 4 def __init__(self, parent=None): QtWidgets.QWidget.__init__(self, parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) while self.name1 == '' or self.group1 == '': dialog = StartDialog(self) if dialog.exec_(): self.name1 = dialog.lineEdit.text() self.group1 = dialog.lineEdit_2.text() self.duration = 0 self.playerState = QMediaPlayer.StoppedState self.timerAud = QtCore.QTimer(self) self.player = QMediaPlayer() self.playlist = QMediaPlaylist() self.player.setPlaylist(self.playlist) # frame with buttons play and stop, and duration label self.frame = QtWidgets.QFrame(self.ui.scrollAreaWidgetContents) self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel) self.frame.setFrameShadow(QtWidgets.QFrame.Raised) self.frame.setObjectName("frame") self.horizontalLayout = QtWidgets.QHBoxLayout(self.frame) self.horizontalLayout.setObjectName("horizontalLayout") self.pushButton = QtWidgets.QPushButton(self.frame) self.pushButton.setObjectName("pushButton") self.horizontalLayout.addWidget(self.pushButton) self.pushButton_3 = QtWidgets.QPushButton(self.frame) self.pushButton_3.setObjectName("pushButton_3") self.horizontalLayout.addWidget(self.pushButton_3) self.labelDuration = QtWidgets.QLabel(self.frame) self.labelDuration.setText('0') self.horizontalLayout.addWidget(self.labelDuration) # creating timer self.timer = QtCore.QTimer(self) # xml handling (read & mix) self.mixXml() # read to DOM self.readToDom() # assigning layout to the scrollarea self.verticalLayout = QtWidgets.QVBoxLayout( self.ui.scrollAreaWidgetContents) self.verticalLayout.setObjectName("verticalLayout") # adding title self.trTitle = QtWidgets.QLabel(self.ui.scrollAreaWidgetContents) self.trTitle.setAlignment(QtCore.Qt.AlignLeading | QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop) self.trTitle.setText('') # adding standart widgets for listening self.verticalLayout.addWidget(self.trTitle) self.lblAud = QtWidgets.QLabel(self.ui.scrollAreaWidgetContents) self.lblAud.setAlignment(QtCore.Qt.AlignLeading | QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop) self.lblAud.setText('') self.horizontalSlider = QtWidgets.QSlider( self.ui.scrollAreaWidgetContents) self.horizontalSlider.setOrientation(QtCore.Qt.Horizontal) self.horizontalSlider.setObjectName("horizontalSlider") # adding frame self.verticalLayout.addWidget(self.lblAud) self.verticalLayout.addWidget(self.horizontalSlider) self.verticalLayout.addWidget(self.frame) self.pushButton.setIcon(self.style().standardIcon( QtWidgets.QStyle.SP_MediaPlay)) self.pushButton_3.setIcon(self.style().standardIcon( QtWidgets.QStyle.SP_MediaStop)) self.pushButton_3.setEnabled(False) # adding widgets to the scrollarea self.addWidgetsToInterface() self.timer.timeout.connect(lambda: self.updater(self.timeSeconds)) # starting timer self.timer.start(1000) self.player.durationChanged.connect(self.durationChanged1) self.player.positionChanged.connect(self.positionChanged1) self.player.stateChanged.connect(self.setState) self.horizontalSlider.setRange(0, self.player.duration() / 1000) self.pushButton.clicked.connect(self.play1) self.pushButton_3.clicked.connect(self.stop1) self.horizontalSlider.sliderMoved.connect(self.changePosition) self.ui.pushButton.clicked.connect(self.finish) def open1(self, filename): self.audiofile = filename fileInfo = QtCore.QFileInfo(self.audiofile) url = QtCore.QUrl.fromLocalFile(fileInfo.absoluteFilePath()) self.playlist.addMedia(QMediaContent(url)) self.pushButton.setEnabled(True) def play1(self): if self.playerState in (QMediaPlayer.StoppedState, QMediaPlayer.PausedState): self.player.play() elif self.playerState == QMediaPlayer.PlayingState: self.player.pause() def stop1(self): self.player.stop() def positionChanged1(self, progress): progress = progress / 1000 if not self.horizontalSlider.isSliderDown(): self.horizontalSlider.setValue(progress) self.updateDurationInfo(progress) def durationChanged1(self, duration): duration = duration / 1000 self.duration = duration self.horizontalSlider.setMaximum(duration) def updateDurationInfo(self, currentInfo): duration = self.duration if currentInfo or duration: currentTime = QtCore.QTime( (currentInfo / 3600) % 60, (currentInfo / 60) % 60, currentInfo % 60, (currentInfo * 1000) % 1000) totalTime = QtCore.QTime((duration / 3600) % 60, (duration / 60) % 60, duration % 60, (duration * 1000) % 1000) format1 = 'hh:mm:ss' if duration > 3600 else 'mm:ss' tStr = currentTime.toString(format1) + " / " + totalTime.toString( format1) else: tStr = '' if (self.timesListening - 1) < 0: self.labelDuration.setText(tStr + ' -осталось количество прослушиваний ' + '0') else: self.labelDuration.setText(tStr + ' -осталось количество прослушиваний ' + str(self.timesListening - 1)) def setState(self, state): if state != self.playerState: self.playerState = state if state == QMediaPlayer.StoppedState: self.timesListening -= 1 if self.timesListening <= 0: self.pushButton.clicked.connect(self.stop1) self.horizontalSlider.setEnabled(False) self.pushButton_3.setEnabled(False) self.pushButton.setIcon(self.style().standardIcon( QtWidgets.QStyle.SP_MediaPlay)) elif state == QMediaPlayer.PlayingState: self.horizontalSlider.setEnabled(True) self.pushButton_3.setEnabled(True) self.pushButton.setIcon(self.style().standardIcon( QtWidgets.QStyle.SP_MediaPause)) elif state == QMediaPlayer.PausedState: self.horizontalSlider.setEnabled(False) self.pushButton_3.setEnabled(True) self.pushButton.setIcon(self.style().standardIcon( QtWidgets.QStyle.SP_MediaPlay)) def changePosition(self, seconds): if self.playerState == QMediaPlayer.PausedState: pass elif self.playerState == QMediaPlayer.PlayingState: self.player.setPosition(seconds * 1000) def finish(self): self.timeRes = self.timeSeconds self.timeSeconds = 0 def mixXml(self): # read xml and mix the lines self.linesMixed = [] self.r = open("db6.xml", 'r', encoding='utf-8') self.fileRead = self.r.readlines() for line in range(2, len(self.fileRead) - 1): self.linesMixed.append(self.fileRead[line]) random.shuffle(self.linesMixed) self.r.close() # write temporary xml with new mixed lines self.w = open("temp.xml", 'w', encoding='utf-8') self.w.write('''<?xml version="1.0" encoding="utf-8"?>\n<content>\n''') for line in self.linesMixed: self.w.write('%s' % line) self.w.write('</content>') self.w.close() def readToDom(self): # read to DOM self.dom = xml.dom.minidom.parse('temp.xml') self.collection = self.dom.documentElement # reading timeout to a variable self.timeSeconds = int( self.collection.getElementsByTagName("time")[0].childNodes[0].data) # reading title self.title = self.collection.getElementsByTagName( "ttl")[0].childNodes[0].data self.questAudio = self.collection.getElementsByTagName( "aud")[0].childNodes[0].data aud = self.collection.getElementsByTagName("aud")[0] audFile = aud.getAttribute('src') self.open1(audFile) self.timeConstant = self.timeSeconds self.linesArr = self.collection.getElementsByTagName("q") for line in range(0, len(self.linesArr)): # label's text self.labels.append(self.linesArr[line].childNodes[0].data) # variants' text self.variants.append( self.linesArr[line].getAttribute('ans').split('**?**')) # correct answer self.correct.append(self.linesArr[line].getAttribute('cor')) # value self.value.append(int(self.linesArr[line].getAttribute('pnt'))) # reading type self.tp.append(self.linesArr[line].getAttribute('type')) # adding picture name if any if self.linesArr[line].hasAttribute('pic'): self.picName.append(self.linesArr[line].getAttribute('pic')) else: self.picName.append('empty') # Mix variants for variant in self.variants: random.shuffle(variant) # Deleting temporary file os.remove('temp.xml') def addWidgetsToInterface(self): # adding widgets to the scrollarea self.trTitle.setText("Тренажер %s" % self.title) self.lblAud.setText("<b>%s</b>" % self.questAudio) for line in range(0, len(self.labels)): self.lbs.append(QtWidgets.QLabel(self.ui.scrollAreaWidgetContents)) self.lbs[line].setAlignment(QtCore.Qt.AlignLeading | QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop) self.lbs[line].setText('<b>%s</b>' % self.labels[line]) self.verticalLayout.addWidget(self.lbs[line]) # adding picture if self.picName[line] != 'empty': self.lblPic.append( QtWidgets.QLabel(self.ui.scrollAreaWidgetContents)) self.lblPic[line].setAlignment(QtCore.Qt.AlignLeading | QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop) self.lblPic[line].setPixmap( QtGui.QPixmap(os.getcwd() + "/" + self.picName[line])) self.verticalLayout.addWidget(self.lblPic[line]) else: self.lblPic.append( QtWidgets.QLabel(self.ui.scrollAreaWidgetContents)) # adding button group self.bgrs.append(QtWidgets.QButtonGroup(self.ui.centralwidget)) if self.tp[line] == 'chb': self.bgrs[line].setExclusive(False) self.correct[line] = self.correct[line].split('**?**') # click counter self.bgrs[line].buttonClicked.connect(self.increaseNum) for v in range(0, len(self.variants[line])): # check br/chb if self.tp[line] == 'rb': self.rbs[line][v] = QtWidgets.QRadioButton( self.ui.scrollAreaWidgetContents) elif self.tp[line] == 'chb': self.rbs[line][v] = QtWidgets.QCheckBox( self.ui.scrollAreaWidgetContents) self.bgrs[line].addButton(self.rbs[line][v]) self.rbs[line][v].setText(self.variants[line][v]) self.verticalLayout.addWidget(self.rbs[line][v]) def increaseNum(self): self.triggeredNum += 1 def check(self): counter = 0 for group in range(0, len(self.bgrs)): # adding questions self.logStr += self.labels[group] + '\n' self.logStr += 'Сложность: %d\n' % self.value[group] # check rb/chb if self.tp[group] == 'rb': self.minNum += 1 correctThis = '--' for rb in self.bgrs[group].buttons(): # adding variants self.logStr += '\t' + rb.text() + '\n' if rb.isChecked(): if rb.text() == self.correct[group]: correctThis = rb.text() counter += self.value[group] elif self.tp[group] == 'chb': if self.correct[group][0] != 'none': self.minNum += len(self.correct[group]) correctThis = [] chbCor = [] for rb in self.bgrs[group].buttons(): # adding variants self.logStr += '\t' + rb.text() + '\n' if rb.isChecked(): # marked checkboxes chbCor.append(rb.text()) if len(chbCor) == 0: chbCor.append('none') chbCor.sort() self.correct[group].sort() if self.correct[group] == chbCor: counter += self.value[group] correctThis = chbCor self.logStr += 'Правильный ответ: %s' % self.listToString( self.correct[group]) + '\n' self.logStr += 'Ответ пользователя: %s' % self.listToString( correctThis) + '\n' if self.listToString( self.correct[group]) == self.listToString(correctThis): self.logStr += 'TRUE\n' else: self.logStr += 'FALSE\n' self.logStr += '\n' # And this is the result! Rounded to 2 decimal points self.result = float(counter / sum(self.value) * 100) message = "Your result is " + "%.2f" % self.result + "%" self.ui.statusbar.setStyleSheet('color: navy; font-weight: bold;') self.ui.statusbar.showMessage(message) # creating log file self.log() def listToString(self, getlist): if type(getlist).__name__ == 'list': string = '' for i in getlist: string += i + '; ' string = string[:-2] + '.' return string else: return getlist def updater(self, val): val = self.timeSeconds if val == 0: self.timer.stop() self.check() self.ui.scrollArea.setEnabled(False) self.ui.pushButton.setEnabled(False) self.ui.label.setText(self.intToTime(val)) self.timeSeconds -= 1 def intToTime(self, num): h = 0 m = 0 if num >= 3600: h = num // 3600 num = num % 3600 if num >= 60: m = num // 60 num = num % 60 s = num str1 = "%d." % h if m < 10: str1 += "0%d:" % m else: str1 += "%d:" % m if s < 10: str1 += "0%d" % s else: str1 += "%d" % s return str1 # returns time as a string def log(self): logFileName = self.name1 + '_' + self.group1 + '_%.2f' % self.result + '_' + str( self.timeConstant - self.timeRes) + '_%.2f' % ( self.triggeredNum / self.minNum * 100) + '_' + str( int(round(time.time() * 1000))) + '.txt' file = open(logFileName, 'w', encoding='utf-8') file.write("Тренажер: %s\n" % self.title) file.write("Имя: %s\nГруппа: %s\n" % (self.name1, self.group1)) file.write("Дата и время записи: ") file.write(time.strftime("%Y-%m-%d %H:%M:%S")) file.write('\n\n') file.write(self.logStr) file.write('\n') file.write("Результат: %.2f" % self.result + " %\n") file.write('Выполнено за %d с\n' % (self.timeConstant - self.timeRes)) # Nubmer of iteractions in percent relative to minimal number of interactions. # Minimal number of iteractions equals the quantity of radio buttons # multiplied by the quantity of correct variants in questions with check boxes # see line 140 and 150-151. file.write('Коэффициент интеракций: %.2f' % (self.triggeredNum / self.minNum * 100) + ' %') # makes log file read only os.chmod(os.path.abspath(logFileName), stat.S_IREAD) file.close() self.triggeredNum = 0 self.logStr = ''
class VKwindow(QWidget): def __init__(self, vkapi): super().__init__() self.vk = vkapi self.initUI() def initUI(self): self.player = QMediaPlayer() self.playlist = QMediaPlaylist() vbox = QVBoxLayout() hbox = QHBoxLayout() self.setGeometry(300, 300, 290, 150) self.slider = QSlider(Qt.Horizontal) self.playBtn = QPushButton('►') self.nextBtn = QPushButton('>') self.prevBtn = QPushButton('<') self.nextBtn.clicked.connect(self.nextSong) self.prevBtn.clicked.connect(self.prevSong) self.playBtn.clicked.connect(self.playSong) self.setWindowTitle('VK music') self.list = QListWidget(self) self.list.currentItemChanged.connect(self.selectSong) for track in self.vk.method('audio.get').get('items'): self.list.addItem(SongWidgetItem(track)) self.playlist.addMedia(QMediaContent(QUrl(track['url']))) hbox.addWidget(self.prevBtn) hbox.addWidget(self.playBtn) hbox.addWidget(self.nextBtn) hbox.addWidget(self.slider) self.player.setPlaylist(self.playlist) self.player.positionChanged.connect(self.setPosition) vbox.addWidget(self.list) vbox.addLayout(hbox) self.setLayout(vbox) self.show() def selectSong(self, curr, prev): self.currentTrack = curr print(curr.getArtist()) def playSong(self): print(self.currentTrack.getArtist()) print(self.list.currentRow()) if self.player.state() == QMediaPlayer.PlayingState and self.list.currentRow() == self.playlist.currentIndex(): self.player.pause() return elif self.player.state() == QMediaPlayer.PausedState: self.player.play() return self.playlist.setCurrentIndex(self.list.currentRow()) self.slider.setTickInterval(self.player.duration()) self.player.play() def setPosition(self, pos): print(pos) self.slider.setTickPosition(pos) def nextSong(self): tmp = self.list.currentRow() size = self.list.count() tmp = (tmp + 1) % size self.list.setCurrentRow(tmp) self.playlist.setCurrentIndex(tmp) self.player.play() def prevSong(self): tmp = self.list.currentRow() size = self.list.count() tmp = (tmp - 1) % size self.list.setCurrentRow(tmp) self.playlist.setCurrentIndex(tmp) self.player.play()
class Player(QWidget): fullScreenChanged = pyqtSignal(bool) def __init__(self, playlist, parent=None): super(Player, self).__init__(parent) self.colorDialog = None self.trackInfo = "" self.statusInfo = "" self.duration = 0 self.player = QMediaPlayer() self.playlist = QMediaPlaylist() self.player.setPlaylist(self.playlist) self.player.durationChanged.connect(self.durationChanged) self.player.positionChanged.connect(self.positionChanged) self.player.metaDataChanged.connect(self.metaDataChanged) self.playlist.currentIndexChanged.connect(self.playlistPositionChanged) self.player.mediaStatusChanged.connect(self.statusChanged) self.player.bufferStatusChanged.connect(self.bufferingProgress) self.player.videoAvailableChanged.connect(self.videoAvailableChanged) self.player.error.connect(self.displayErrorMessage) self.videoWidget = VideoWidget() self.player.setVideoOutput(self.videoWidget) self.playlistModel = PlaylistModel() self.playlistModel.setPlaylist(self.playlist) self.playlistView = QListView() self.playlistView.setModel(self.playlistModel) self.playlistView.setCurrentIndex( self.playlistModel.index(self.playlist.currentIndex(), 0)) self.playlistView.activated.connect(self.jump) self.slider = QSlider(Qt.Horizontal) self.slider.setRange(0, self.player.duration() / 1000) self.labelDuration = QLabel() self.slider.sliderMoved.connect(self.seek) self.labelHistogram = QLabel() self.labelHistogram.setText("Histogram:") self.histogram = HistogramWidget() histogramLayout = QHBoxLayout() histogramLayout.addWidget(self.labelHistogram) histogramLayout.addWidget(self.histogram, 1) self.probe = QVideoProbe() self.probe.videoFrameProbed.connect(self.histogram.processFrame) self.probe.setSource(self.player) openButton = QPushButton("Open", clicked=self.open) controls = PlayerControls() controls.setState(self.player.state()) controls.setVolume(self.player.volume()) controls.setMuted(controls.isMuted()) controls.play.connect(self.player.play) controls.pause.connect(self.player.pause) controls.stop.connect(self.player.stop) controls.next.connect(self.playlist.next) controls.previous.connect(self.previousClicked) controls.changeVolume.connect(self.player.setVolume) controls.changeMuting.connect(self.player.setMuted) controls.changeRate.connect(self.player.setPlaybackRate) controls.stop.connect(self.videoWidget.update) self.player.stateChanged.connect(controls.setState) self.player.volumeChanged.connect(controls.setVolume) self.player.mutedChanged.connect(controls.setMuted) self.fullScreenButton = QPushButton("FullScreen") self.fullScreenButton.setCheckable(True) self.colorButton = QPushButton("Color Options...") self.colorButton.setEnabled(False) self.colorButton.clicked.connect(self.showColorDialog) displayLayout = QHBoxLayout() displayLayout.addWidget(self.videoWidget, 2) displayLayout.addWidget(self.playlistView) controlLayout = QHBoxLayout() controlLayout.setContentsMargins(0, 0, 0, 0) controlLayout.addWidget(openButton) controlLayout.addStretch(1) controlLayout.addWidget(controls) controlLayout.addStretch(1) controlLayout.addWidget(self.fullScreenButton) controlLayout.addWidget(self.colorButton) layout = QVBoxLayout() layout.addLayout(displayLayout) hLayout = QHBoxLayout() hLayout.addWidget(self.slider) hLayout.addWidget(self.labelDuration) layout.addLayout(hLayout) layout.addLayout(controlLayout) layout.addLayout(histogramLayout) self.setLayout(layout) if not self.player.isAvailable(): QMessageBox.warning(self, "Service not available", "The QMediaPlayer object does not have a valid service.\n" "Please check the media service plugins are installed.") controls.setEnabled(False) self.playlistView.setEnabled(False) openButton.setEnabled(False) self.colorButton.setEnabled(False) self.fullScreenButton.setEnabled(False) self.metaDataChanged() self.addToPlaylist(playlist) def open(self): fileNames, _ = QFileDialog.getOpenFileNames(self, "Open Files") self.addToPlaylist(fileNames) def addToPlaylist(self, fileNames): for name in fileNames: fileInfo = QFileInfo(name) if fileInfo.exists(): url = QUrl.fromLocalFile(fileInfo.absoluteFilePath()) if fileInfo.suffix().lower() == 'm3u': self.playlist.load(url) else: self.playlist.addMedia(QMediaContent(url)) else: url = QUrl(name) if url.isValid(): self.playlist.addMedia(QMediaContent(url)) def durationChanged(self, duration): duration /= 1000 self.duration = duration self.slider.setMaximum(duration) def positionChanged(self, progress): progress /= 1000 if not self.slider.isSliderDown(): self.slider.setValue(progress) self.updateDurationInfo(progress) def metaDataChanged(self): if self.player.isMetaDataAvailable(): self.setTrackInfo("%s - %s" % ( self.player.metaData(QMediaMetaData.AlbumArtist), self.player.metaData(QMediaMetaData.Title))) def previousClicked(self): # Go to the previous track if we are within the first 5 seconds of # playback. Otherwise, seek to the beginning. if self.player.position() <= 5000: self.playlist.previous() else: self.player.setPosition(0) def jump(self, index): if index.isValid(): self.playlist.setCurrentIndex(index.row()) self.player.play() def playlistPositionChanged(self, position): self.playlistView.setCurrentIndex( self.playlistModel.index(position, 0)) def seek(self, seconds): self.player.setPosition(seconds * 1000) def statusChanged(self, status): self.handleCursor(status) if status == QMediaPlayer.LoadingMedia: self.setStatusInfo("Loading...") elif status == QMediaPlayer.StalledMedia: self.setStatusInfo("Media Stalled") elif status == QMediaPlayer.EndOfMedia: QApplication.alert(self) elif status == QMediaPlayer.InvalidMedia: self.displayErrorMessage() else: self.setStatusInfo("") def handleCursor(self, status): if status in (QMediaPlayer.LoadingMedia, QMediaPlayer.BufferingMedia, QMediaPlayer.StalledMedia): self.setCursor(Qt.BusyCursor) else: self.unsetCursor() def bufferingProgress(self, progress): self.setStatusInfo("Buffering %d%" % progress) def videoAvailableChanged(self, available): if available: self.fullScreenButton.clicked.connect( self.videoWidget.setFullScreen) self.videoWidget.fullScreenChanged.connect( self.fullScreenButton.setChecked) if self.fullScreenButton.isChecked(): self.videoWidget.setFullScreen(True) else: self.fullScreenButton.clicked.disconnect( self.videoWidget.setFullScreen) self.videoWidget.fullScreenChanged.disconnect( self.fullScreenButton.setChecked) self.videoWidget.setFullScreen(False) self.colorButton.setEnabled(available) def setTrackInfo(self, info): self.trackInfo = info if self.statusInfo != "": self.setWindowTitle("%s | %s" % (self.trackInfo, self.statusInfo)) else: self.setWindowTitle(self.trackInfo) def setStatusInfo(self, info): self.statusInfo = info if self.statusInfo != "": self.setWindowTitle("%s | %s" % (self.trackInfo, self.statusInfo)) else: self.setWindowTitle(self.trackInfo) def displayErrorMessage(self): self.setStatusInfo(self.player.errorString()) def updateDurationInfo(self, currentInfo): duration = self.duration if currentInfo or duration: currentTime = QTime((currentInfo/3600)%60, (currentInfo/60)%60, currentInfo%60, (currentInfo*1000)%1000) totalTime = QTime((duration/3600)%60, (duration/60)%60, duration%60, (duration*1000)%1000); format = 'hh:mm:ss' if duration > 3600 else 'mm:ss' tStr = currentTime.toString(format) + " / " + totalTime.toString(format) else: tStr = "" self.labelDuration.setText(tStr) def showColorDialog(self): if self.colorDialog is None: brightnessSlider = QSlider(Qt.Horizontal) brightnessSlider.setRange(-100, 100) brightnessSlider.setValue(self.videoWidget.brightness()) brightnessSlider.sliderMoved.connect( self.videoWidget.setBrightness) self.videoWidget.brightnessChanged.connect( brightnessSlider.setValue) contrastSlider = QSlider(Qt.Horizontal) contrastSlider.setRange(-100, 100) contrastSlider.setValue(self.videoWidget.contrast()) contrastSlider.sliderMoved.connect(self.videoWidget.setContrast) self.videoWidget.contrastChanged.connect(contrastSlider.setValue) hueSlider = QSlider(Qt.Horizontal) hueSlider.setRange(-100, 100) hueSlider.setValue(self.videoWidget.hue()) hueSlider.sliderMoved.connect(self.videoWidget.setHue) self.videoWidget.hueChanged.connect(hueSlider.setValue) saturationSlider = QSlider(Qt.Horizontal) saturationSlider.setRange(-100, 100) saturationSlider.setValue(self.videoWidget.saturation()) saturationSlider.sliderMoved.connect( self.videoWidget.setSaturation) self.videoWidget.saturationChanged.connect( saturationSlider.setValue) layout = QFormLayout() layout.addRow("Brightness", brightnessSlider) layout.addRow("Contrast", contrastSlider) layout.addRow("Hue", hueSlider) layout.addRow("Saturation", saturationSlider) button = QPushButton("Close") layout.addRow(button) self.colorDialog = QDialog(self) self.colorDialog.setWindowTitle("Color Options") self.colorDialog.setLayout(layout) button.clicked.connect(self.colorDialog.close) self.colorDialog.show()