class CameraWidget(QWidget): def __init__(self, background_color): QWidget.__init__(self) self.scene = QGraphicsScene(self) self.scene.setBackgroundBrush(QBrush(background_color)) self.graphics_view = QGraphicsView(self.scene) self.graphics_view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.graphics_view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.graphics_view.setFrameStyle(0) self.graphics_view.setStyleSheet("QGraphicsView {background: transparent; border: 3px; outline: none;}") self.graphics_view.scale(-1, 1) # this make live video from camero mirror. self.video_item = QGraphicsVideoItem() self.scene.addItem(self.video_item) self.layout = QVBoxLayout(self) self.layout.setContentsMargins(0, 0, 0, 0) self.layout.addWidget(self.graphics_view) self.available_cameras = QCameraInfo.availableCameras() # Set the default camera. self.select_camera(0) def resizeEvent(self, event): self.video_item.setSize(QSizeF(event.size().width(), event.size().height())) QWidget.resizeEvent(self, event) def select_camera(self, i): self.camera = QCamera(self.available_cameras[i]) self.camera.setViewfinder(self.video_item) self.camera.setCaptureMode(QCamera.CaptureStillImage) self.camera.start()
class VideoPlayerWidget(QWidget): def __init__(self, parent=None): super(VideoPlayerWidget, self).__init__(parent) self.scene = QGraphicsScene(self) self.scene.setBackgroundBrush(QBrush(QColor(0, 0, 0, 255))) self.graphics_view = QGraphicsView(self.scene) self.graphics_view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.graphics_view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.graphics_view.setFrameStyle(0) self.graphics_view.setStyleSheet( "QGraphicsView {background: transparent; border: 3px; outline: none;}" ) self.video_item = QGraphicsVideoItem() self.scene.addItem(self.video_item) self.layout = QVBoxLayout(self) self.layout.setContentsMargins(0, 0, 0, 0) self.layout.addWidget(self.graphics_view) self.media_player = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.media_player.setVideoOutput(self.video_item) self.video_need_replay = False self.video_seek_durcation = 3000 # in milliseconds def resizeEvent(self, event): self.video_item.setSize( QSizeF(event.size().width(), event.size().height())) QWidget.resizeEvent(self, event) def play(self, url): self.media_player.setMedia(QMediaContent(QUrl.fromLocalFile(url))) self.media_player.play() def seek_forward(self): video_position = self.media_player.position() self.media_player.setPosition(video_position + self.video_seek_durcation) def seek_backward(self): video_position = self.media_player.position() self.media_player.setPosition( max(video_position - self.video_seek_durcation, 0)) def keyPressEvent(self, event): if event.key() == Qt.Key_Space: if self.media_player.state() == QMediaPlayer.PlayingState: self.media_player.pause() self.video_need_replay = False else: self.media_player.play() self.video_need_replay = True elif event.key() == Qt.Key_H: self.seek_backward() elif event.key() == Qt.Key_L: self.seek_forward()
class CameraWidget(QWidget): def __init__(self, background_color): QWidget.__init__(self) self.scene = QGraphicsScene(self) self.scene.setBackgroundBrush(QBrush(background_color)) self.graphics_view = QGraphicsView(self.scene) self.graphics_view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.graphics_view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.graphics_view.setFrameStyle(0) self.graphics_view.setStyleSheet( "QGraphicsView {background: transparent; border: 3px; outline: none;}" ) self.graphics_view.scale(-1, 1) # this make live video from camero mirror. self.video_item = QGraphicsVideoItem() self.scene.addItem(self.video_item) self.layout = QVBoxLayout(self) self.layout.setContentsMargins(0, 0, 0, 0) self.layout.addWidget(self.graphics_view) self.available_cameras = QCameraInfo.availableCameras() # Set the default camera. self.select_camera(0) def resizeEvent(self, event): self.video_item.setSize( QSizeF(event.size().width(), event.size().height())) QWidget.resizeEvent(self, event) def select_camera(self, i): self.camera = QCamera(self.available_cameras[i]) self.camera.setViewfinder(self.video_item) self.camera.setCaptureMode(QCamera.CaptureStillImage) self.camera.start() def take_photo(self, camera_save_path): image_capture = QCameraImageCapture(self.camera) try: save_path = str(Path(os.path.expanduser(camera_save_path))) photo_path = os.path.join( save_path, "EAF_Camera_Photo_" + time.strftime( "%Y-%m-%d_%H:%M:%S", time.localtime(int(time.time())))) image_capture.capture(photo_path) except: save_path = str(Path(os.path.expanduser("~/Downloads"))) photo_path = os.path.join( save_path, "EAF_Camera_Photo_" + time.strftime( "%Y-%m-%d_%H:%M:%S", time.localtime(int(time.time())))) image_capture.capture(photo_path) self.message_to_emacs.emit("Save photo at: " + photo_path)
class VideoPlayerWidget(QWidget): def __init__(self, parent=None): super(VideoPlayerWidget, self).__init__(parent) self.scene = QGraphicsScene(self) self.scene.setBackgroundBrush(QBrush(QColor(0, 0, 0, 255))) self.graphics_view = QGraphicsView(self.scene) self.graphics_view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.graphics_view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.graphics_view.setFrameStyle(0) self.graphics_view.setStyleSheet("QGraphicsView {background: transparent; border: 3px; outline: none;}") self.video_item = QGraphicsVideoItem() self.scene.addItem(self.video_item) self.layout = QVBoxLayout(self) self.layout.setContentsMargins(0, 0, 0, 0) self.layout.addWidget(self.graphics_view) self.media_player = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.media_player.setVideoOutput(self.video_item) self.video_need_replay = False self.video_seek_durcation = 3000 # in milliseconds def resizeEvent(self, event): self.video_item.setSize(QSizeF(event.size().width(), event.size().height())) QWidget.resizeEvent(self, event) def play(self, url): self.media_player.setMedia(QMediaContent(QUrl.fromLocalFile(url))) self.media_player.play() def seek_forward(self): video_position = self.media_player.position() self.media_player.setPosition(video_position + self.video_seek_durcation) def seek_backward(self): video_position = self.media_player.position() self.media_player.setPosition(max(video_position - self.video_seek_durcation, 0)) def keyPressEvent(self, event): if event.key() == Qt.Key_Space: if self.media_player.state() == QMediaPlayer.PlayingState: self.media_player.pause() self.video_need_replay = False else: self.media_player.play() self.video_need_replay = True elif event.key() == Qt.Key_H: self.seek_backward() elif event.key() == Qt.Key_L: self.seek_forward()
class NowPlayingWidget(QtWidgets.QGraphicsView): def __init__(self, media_player): super().__init__() self._media_player = media_player self._media_player.currentMediaChanged.connect(self.change_title) self.setScene(QtWidgets.QGraphicsScene(self)) self.init_ui() def set_opacity(self, value): self._opacity = value self.overlay.setOpacity(value) def init_ui(self): self.main_layout = QtWidgets.QVBoxLayout() self.main_layout.setContentsMargins(0, 0, 0, 0) self.setFixedHeight(200) self.now_playing_visual = NowPlayingVisual(self._media_player, self) self.main_layout.addWidget(self.now_playing_visual) self.setBackgroundBrush(QtGui.QBrush(QtCore.Qt.black)) self.video_item = QGraphicsVideoItem() self.video_item.setGraphicsEffect(QtWidgets.QGraphicsBlurEffect()) self.video_item.setAspectRatioMode( QtCore.Qt.KeepAspectRatioByExpanding) self._media_player.setVideoOutput(self.video_item) self.scene().addItem(self.video_item) self.overlay = QtWidgets.QGraphicsRectItem(0, 0, 0, 0, self.video_item) self.overlay.setBrush(QtGui.QBrush(QtCore.Qt.black)) self.set_opacity(0.8) self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) self.setStyleSheet('border: 0px;') self.setLayout(self.main_layout) def change_title(self, media): data = self._media_player.nowplaying() if data: self.now_playing_visual.set_title(data) def resizeEvent(self, event): self.video_item.setSize(QtCore.QSizeF(self.size())) rect = QtCore.QRectF(0, 0, self.video_item.size().width(), self.video_item.size().height()) self.overlay.setRect(rect)
def __init__(self, width: int, height: int, parent=None): super(VideoPlayer, self).__init__(parent) video_item = QGraphicsVideoItem() video_item.setAspectRatioMode(Qt.IgnoreAspectRatio) video_item.setSize(QSizeF(width, height)) scene = QGraphicsScene(self) scene.addItem(video_item) graphics_view = QGraphicsView(scene) graphics_view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) graphics_view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) layout = QVBoxLayout() layout.addWidget(graphics_view) self.setLayout(layout) self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.mediaPlayer.setVideoOutput(video_item) self.mediaPlayer.setVolume(0)
class CameraWidget(QWidget): def __init__(self, background_color): QWidget.__init__(self) self.scene = QGraphicsScene(self) self.scene.setBackgroundBrush(QBrush(background_color)) self.graphics_view = QGraphicsView(self.scene) self.graphics_view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.graphics_view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.graphics_view.setFrameStyle(QFrame.NoFrame) self.graphics_view.scale(-1, 1) # this make live video from camero mirror. self.video_item = QGraphicsVideoItem() self.scene.addItem(self.video_item) self.layout = QVBoxLayout(self) self.layout.setSpacing(0) self.layout.setContentsMargins(0, 0, 0, 0) self.layout.addWidget(self.graphics_view) self.available_cameras = QCameraInfo.availableCameras() # Set the default camera. self.select_camera(0) def resizeEvent(self, event): self.video_item.setSize( QSizeF(event.size().width(), event.size().height())) QWidget.resizeEvent(self, event) def select_camera(self, i): self.camera = QCamera(self.available_cameras[i]) self.camera.setViewfinder(self.video_item) self.camera.setCaptureMode(QCamera.CaptureStillImage) self.camera.start() def take_photo(self, camera_save_path): image_capture = QCameraImageCapture(self.camera) save_path = str(Path(os.path.expanduser(camera_save_path))) photo_path = os.path.join( save_path, "EAF_Camera_Photo_" + time.strftime("%Y%m%d_%H%M%S", time.localtime(int(time.time())))) return image_capture.capture(photo_path) def stop_camera(self): self.camera.stop()
class Video(QMainWindow): def __init__(self): super(Video, self).__init__() self.resize(1920, 1080) self._item = QGraphicsVideoItem() self._view = QGraphicsView() self._scene = QGraphicsScene() self._view.resize(1920, 1080) self._view.setScene(self._scene) self._scene.addItem(self._item) self._view.show() self._item.setSize(QSizeF(1920, 1080)) self._player = QMediaPlayer(self) self._player.setMedia( QMediaContent( QUrl.fromLocalFile( '/Users/huangkai/Documents/PycharmProjects/AllTest/Qt插入背景/AddVideos/Videos/yellow.mov' ))) self._player.setVideoOutput(self._item) self._player.play() self.setCentralWidget(self._view)
class Video(QMainWindow): def __init__(self): super(Video, self).__init__() self.resize(1920, 1080) # ITEM self._item = QGraphicsVideoItem() self._textItem = QGraphicsTextItem() self._view = QGraphicsView() self._scene = QGraphicsScene() self._view.resize(1920, 1080) self._view.setScene(self._scene) self._scene.addItem(self._item) self._scene.addItem(self._textItem) self._textItem.setPlainText('SRT TEXT') self._textItem.setDefaultTextColor(Qt.red) font = self._textItem.font() font.setPixelSize(50) self._textItem.setFont(font) self._view.show() self._item.setSize(QSizeF(1920, 1080)) self._player = QMediaPlayer(self) self._player.setMedia( QMediaContent( QUrl.fromLocalFile( '/Users/huangkai/Documents/PycharmProjects/AllTest/Qt插入背景/AddVideos/Videos/yellow.mov' ))) self._player.setVideoOutput(self._item) self._player.play() self.setCentralWidget(self._view) self._item.setPos(400, 500) # BUTTON self._btn = QPushButton(self) self._btn.resize(100, 50) self._btn.move(500, 500) self._btn.setText('test') self._btn.clicked.connect(self._change_text) def _change_text(self): self._textItem.setPlainText('Fighting')
class CameraWidget(QWidget): def __init__(self, background_color): QWidget.__init__(self) self.scene = QGraphicsScene(self) self.scene.setBackgroundBrush(QBrush(background_color)) self.graphics_view = QGraphicsView(self.scene) self.graphics_view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.graphics_view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.graphics_view.setFrameStyle(0) self.graphics_view.setStyleSheet( "QGraphicsView {background: transparent; border: 3px; outline: none;}" ) self.graphics_view.scale(-1, 1) # this make live video from camero mirror. self.video_item = QGraphicsVideoItem() self.scene.addItem(self.video_item) self.layout = QVBoxLayout(self) self.layout.setContentsMargins(0, 0, 0, 0) self.layout.addWidget(self.graphics_view) self.available_cameras = QCameraInfo.availableCameras() # Set the default camera. self.select_camera(0) def resizeEvent(self, event): self.video_item.setSize( QSizeF(event.size().width(), event.size().height())) QWidget.resizeEvent(self, event) def select_camera(self, i): self.camera = QCamera(self.available_cameras[i]) self.camera.setViewfinder(self.video_item) self.camera.setCaptureMode(QCamera.CaptureStillImage) self.camera.start()
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 VideoPlayer(QWidget): def __init__(self, parent=None): super(VideoPlayer, self).__init__(parent) self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.videoItem = QGraphicsVideoItem() self.videoItem.setSize(QSizeF(640, 480)) scene = QGraphicsScene(self) graphicsView = QGraphicsView(scene) scene.addItem(self.videoItem) rotateSlider = QSlider(Qt.Horizontal) rotateSlider.setRange(-180, 180) rotateSlider.setValue(0) rotateSlider.valueChanged.connect(self.rotateVideo) openButton = QPushButton("Open...") openButton.clicked.connect(self.openFile) self.playButton = QPushButton() self.playButton.setEnabled(False) self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay)) self.playButton.clicked.connect(self.play) self.positionSlider = QSlider(Qt.Horizontal) self.positionSlider.setRange(0, 0) self.positionSlider.sliderMoved.connect(self.setPosition) controlLayout = QHBoxLayout() controlLayout.setContentsMargins(0, 0, 0, 0) controlLayout.addWidget(openButton) controlLayout.addWidget(self.playButton) controlLayout.addWidget(self.positionSlider) layout = QVBoxLayout() layout.addWidget(graphicsView) layout.addWidget(rotateSlider) layout.addLayout(controlLayout) self.setLayout(layout) self.mediaPlayer.setVideoOutput(self.videoItem) self.mediaPlayer.stateChanged.connect(self.mediaStateChanged) self.mediaPlayer.positionChanged.connect(self.positionChanged) self.mediaPlayer.durationChanged.connect(self.durationChanged) def sizeHint(self): return QSize(800, 600) def openFile(self): fileName, _ = QFileDialog.getOpenFileName(self, "Open Movie", QDir.homePath()) if fileName != '': self.mediaPlayer.setMedia( QMediaContent(QUrl.fromLocalFile(fileName))) self.playButton.setEnabled(True) def play(self): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.mediaPlayer.pause() else: self.mediaPlayer.play() def mediaStateChanged(self, state): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.playButton.setIcon( self.style().standardIcon(QStyle.SP_MediaPause)) else: self.playButton.setIcon( self.style().standardIcon(QStyle.SP_MediaPlay)) def positionChanged(self, position): self.positionSlider.setValue(position) def durationChanged(self, duration): self.positionSlider.setRange(0, duration) def setPosition(self, position): self.mediaPlayer.setPosition(position) def rotateVideo(self, angle): x = self.videoItem.boundingRect().width() / 2.0 y = self.videoItem.boundingRect().height() / 2.0 self.videoItem.setTransform( QTransform().translate(x, y).rotate(angle).translate(-x, -y))
class LiveFeedWidget(QGraphicsView): class _State(Enum): Init = "Init" Idle = "Idle" Preparing = "Preparing" WaitingForCapture = "WaitingForCapture" error = pyqtSignal(str) image_captured = pyqtSignal(QImage) initialized = pyqtSignal() def __init__( self, camera: Camera, is_mirrored: bool, mask: Mask, parent=None, ): super().__init__(parent=parent) self._is_mirrored = is_mirrored self._mask = mask self._state = LiveFeedWidget._State.Init self._video_item = QGraphicsVideoItem() # I think this is the size in pixels on the screen? self._video_item.setSize(QSizeF(self._mask.size)) # TODO I think this will not draw centrally? If not should fix this self._video_item.setAspectRatioMode(Qt.KeepAspectRatioByExpanding) if self._is_mirrored: self._video_item.setTransform(QTransform().scale(-1, 1)) self.setMask(self._mask.clip_region) self._scene: OverlayTextGraphicsScene = OverlayTextGraphicsScene( self._mask.size) self._scene.addItem(self._video_item) self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setScene(self._scene) # Setup camera # self._camera = camera self._camera.setViewfinder(self._video_item) self._camera.setCaptureMode(QCamera.CaptureStillImage) self._camera.error.connect(self._on_camera_error) self._camera.statusChanged.connect(self._on_camera_status_changed) # Setup capture # self._capture = QCameraImageCapture(self._camera) self._capture.setCaptureDestination( QCameraImageCapture.CaptureToBuffer) self._capture.imageCaptured.connect(self._image_captured) self._capture.error.connect(self._on_capture_error) self._camera.start() logger.info("Camera started") def set_overlay_text(self, text: str): self._scene.set_overlay_text(text) def prepare(self): if self._state != LiveFeedWidget._State.Idle: logger.warning("Dropping call to prepare when in state: %s", self._state) else: self._state = LiveFeedWidget._State.Preparing self._camera.searchAndLock() def trigger_capture(self): if self._state != LiveFeedWidget._State.Preparing: logger.warning( "Dropping call to trigger_capture when in state: %s", self._state) else: logger.debug("trigger_capture") self._state = LiveFeedWidget._State.WaitingForCapture self._capture.capture() # noinspection PyPep8Naming def _on_camera_error(self, QCamera_Error: int): self._state = LiveFeedWidget._State.Idle self.error.emit(f"Camera error, code: {QCamera_Error}") # noinspection PyPep8Naming def _on_capture_error(self, p_int=None, QCameraImageCapture_Error=None, p_str=None): self._state = LiveFeedWidget._State.Idle self.error.emit( f"Capture error: {p_int} / {QCameraImageCapture_Error} / {p_str}") def _image_captured(self, id_: int, image: QImage): if self._state != LiveFeedWidget._State.WaitingForCapture: logger.warning("Dropping _image_captured when in state: %s", self._state) self._state = LiveFeedWidget._State.Idle logger.debug("image captured: %s %s", id_, image) self._camera.unlock() # TODO If I don't unload and the reload the camera, gstreamer dies # with CameraBin error: "Internal data stream error.", not sure why # :( self._camera.unload() self.image_captured.emit(_mirror_if_necessary(image, self._is_mirrored)) def reload(self): # See comment on _image_captured self._camera.start() def _on_camera_status_changed(self, status): logger.debug("_on_camera_status_changed: %s", status) if status == QCamera.ActiveStatus: self._state = LiveFeedWidget._State.Idle self.initialized.emit()
class eyeTrackingWidget(QtWidgets.QWidget): def __init__(self, *args, **kwargs): QtWidgets.QWidget.__init__(self, *args, **kwargs) ##################### eye tracking ##################### self.audience_eye_tracking_dic = {} self.eye_track_dic = {} self.elements = {} self.eye_track_frame_rate = 10 self.trial_lapse = 2000 self.eye_tracking_width = 1024 ##eye tracking hardware resolution self.eye_tracking_height = 768 ##eye tracking hardware resolution self.view_width = 1184 ##QGraphicsView resolution self.view_height = 666 ##QGraphcsView ##################### eye tracking ##################### ####### DO NOT TOUCH ####### self.loaded = 0 #self.tl = timeline.timeline(self) #self.tl = timeline.timeline(self) #self.layout.addChildWidget(self.tl) # player.setInterval(self.eye_track_frame_rate) # timer.timeout.connect(self.draw_eye_tracking) ####### DO NOT TOUCH ####### ############################### self.view = QtWidgets.QGraphicsView() self.view.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) self.view.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) self.view.setViewport(PyQt5.QtOpenGL.QGLWidget()) self.view.setFixedSize(self.view_width + 2, self.view_height + 2) self.view.setGeometry(0, 0, self.view_width, self.view_height) self.videoItem = QGraphicsVideoItem() # MUST setsize that is half the size of the GraphicsView # Most likey a bug in Qt's implementation on Mac OS X self.videoItem.setSize( QtCore.QSizeF(self.view_width / 2, self.view_height / 2)) self.player = QM.QMediaPlayer() self.player.setVideoOutput(self.videoItem) self.scene = QtWidgets.QGraphicsScene() self.scene.addItem(self.videoItem) self.view.setScene(self.scene) self.scene.setSceneRect(0, 0, self.view_width, self.view_height) self.videoItem.setPos(0, 0) ############################### self.layout = QtWidgets.QVBoxLayout(self) self.layout.addWidget(self.view) self.createUI() self.view.show() def createUI(self): # video position slider self.positionSlider = QtWidgets.QSlider(QtCore.Qt.Horizontal, self) self.positionSlider.setStyleSheet( "QSlider::groove:horizontal {background-color:grey;}" "QSlider::handle:horizontal {background-color:black; height:8px; width: 8px;}" ) self.positionSlider.sliderMoved.connect(self.setPosition) #self.positionSlider.valueChanged.connect(self.setPosition) # play button self.hbuttonbox = QtWidgets.QHBoxLayout() self.playbutton = QtWidgets.QPushButton("Play") self.hbuttonbox.addWidget(self.playbutton) self.playbutton.clicked.connect(self.play_pause) self.openbutton = QtWidgets.QPushButton("Open") self.hbuttonbox.addWidget(self.openbutton) self.openbutton.clicked.connect(self.open_file) self.openbutton2 = QtWidgets.QPushButton("Open EYE") self.hbuttonbox.addWidget(self.openbutton2) self.openbutton2.clicked.connect(self.open_eye) self.openbutton3 = QtWidgets.QPushButton("Open TL") self.hbuttonbox.addWidget(self.openbutton3) self.openbutton3.clicked.connect(self.open_timeline) self.openbutton4 = QtWidgets.QPushButton("Open EEG") self.hbuttonbox.addWidget(self.openbutton4) self.comboLabel = QtWidgets.QLabel("Select objects:") self.combobox = QtWidgets.QComboBox(self) self.comboboxDelegate = utility.SubclassOfQStyledItemDelegate() self.combobox.setItemDelegate(self.comboboxDelegate) self.combobox.setSizeAdjustPolicy(0) self.hbuttonbox.addWidget(self.comboLabel) self.hbuttonbox.addWidget(self.combobox) self.hbuttonbox.addStretch(1) self.layout.addWidget(self.positionSlider) self.layout.addLayout(self.hbuttonbox) self.player.setNotifyInterval(1000 / self.eye_track_frame_rate) self.player.positionChanged.connect(self.updateUI) self.player.positionChanged.connect(self.updateEyeTracking) self.player.durationChanged.connect(self.setRange) self.player.stateChanged.connect(self.setButtonCaption) self.setLayout(self.layout) def setButtonCaption(self, state): if self.player.state() == QM.QMediaPlayer.PlayingState: self.playbutton.setText("Pause") else: self.playbutton.setText("Play") def open_file(self): home = str(Path.home()) filename, _ = QtWidgets.QFileDialog.getOpenFileName( self, "Open File", home) if not filename: return url = QtCore.QUrl.fromLocalFile(filename) content = QM.QMediaContent(url) self.player.setMedia(content) self.playbutton.setText("Play") def open_eye(self): home = str(Path.home()) filenames, _ = QtWidgets.QFileDialog.getOpenFileNames( self, "Open EYE", home) print("%s, %s" % (filenames, len(filenames))) if not filenames: return object_list = [] self.audience_eye_tracking_dic = {} self.eye_track_dic = {} for filename in filenames: object = os.path.split(filename)[-1].split('_')[0] self.create_eye_tracking_reference_dict( pandas.read_excel(str(filename)), object) object_list.append(object) self.addSelectArea(object_list) def play_pause(self): if self.player.state() == QM.QMediaPlayer.PlayingState: self.player.pause() else: self.player.play() def setPosition(self, position): self.positionSlider.setValue(position) self.player.setPosition(position) def setRange(self): self.positionSlider.setRange(0, self.player.duration()) def updateUI(self, position): self.positionSlider.setValue(position) def updateEyeTracking(self, position): if len(self.eye_track_dic.keys()) == 0: # or self.player.state() != 2: return self.draw_eye_tracking() def addSelectArea(self, objects): self.player.pause() for k in self.elements.keys(): self.removeElement(self.elements[k], k) self.elements = {} self.model = QtGui.QStandardItemModel(len(objects) + 1, 1) # 5 rows, 2 col firstItem = QtGui.QStandardItem("---- Select area(s) ----") firstItem.setBackground(QtGui.QBrush(QtGui.QColor(200, 200, 200))) firstItem.setSelectable(False) self.model.setItem(0, 0, firstItem) num = 0 for obj in objects: num += 1 item = QtGui.QStandardItem(obj) item.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled) itemColor = QtGui.QColor(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) item.setBackground(itemColor) if num <= 2: item.setData(QtCore.Qt.Checked, QtCore.Qt.CheckStateRole) self.elements[item.text()] = { 'dot': None, 'lines': [], 'color': itemColor } else: item.setData(QtCore.Qt.Unchecked, QtCore.Qt.CheckStateRole) self.model.setItem(num, 0, item) self.model.itemChanged.connect(self.update_objects) self.combobox.setModel(self.model) def removeElement(self, element, name): for line in element['lines']: self.scene.removeItem(line) del line self.scene.removeItem(element['dot']) del element['dot'] # del element['color'] self.elements.pop(name) def update_objects(self, item): if item.checkState() == 0: self.removeElement(self.elements[item.text()], item.text()) else: self.elements[item.text()] = { 'dot': None, 'lines': [], 'color': item.background().color() } def draw_dot_line(self, v, obj): pos = v['pos'] rad = v['rad'] if self.elements[obj]['dot'] is not None: self.elements[obj]['dot'].setRect(QtCore.QRectF(0, 0, rad, rad)) else: self.elements[obj]['dot'] = self.scene.addEllipse( QtCore.QRectF(0, 0, rad, rad), QtGui.QPen(QtCore.Qt.red), QtGui.QBrush(self.elements[obj]['color'])) self.elements[obj]['dot'].setPos( QtCore.QPoint(pos[0] - rad / 2, pos[1] - rad / 2)) j = 0 for i in range(len(v['lines'])): j = i if i >= len(self.elements[obj]['lines']): self.elements[obj]['lines'].append( self.scene.addLine( QtCore.QLineF(v['lines'][i][0][0], v['lines'][i][0][1], v['lines'][i][1][0], v['lines'][i][1][1]), QtGui.QPen(self.elements[obj]['color']))) else: self.elements[obj]['lines'][i].setLine( QtCore.QLineF(v['lines'][i][0][0], v['lines'][i][0][1], v['lines'][i][1][0], v['lines'][i][1][1])) if len(self.elements[obj]['lines']) > j: for line in self.elements[obj]['lines'][j + 1:-1]: self.scene.removeItem(line) del line def resolution_transfer(self, x, y, duration): return [x / self.eye_tracking_width * (self.view_width + 2),\ y / self.eye_tracking_height * (self.view_height + 2), \ 3 + duration / 20.0] def create_eye_tracking_reference_dict(self, excel, object): self.audience_eye_tracking_dic[object] = { 'pos': [], 'rad': 0, 'lines': [] } self.eye_track_window = 1000 / self.eye_track_frame_rate self.eye_track_dic[object] = [] last_one = int(excel['CURRENT_FIX_START'][521] / self.eye_track_window) head = 0 for i in range(last_one): start_time = i * self.eye_track_window updated_flag = False while head < len(excel['CURRENT_FIX_START'].index): if excel['CURRENT_FIX_START'][head] > start_time: break if excel['CURRENT_FIX_START'][ head] <= start_time and start_time <= excel[ 'CURRENT_FIX_END'][head]: self.eye_track_dic[object].append( self.resolution_transfer( excel['CURRENT_FIX_X'][head], excel['CURRENT_FIX_Y'][head], excel['CURRENT_FIX_DURATION'][head])) updated_flag = True break head += 1 if not updated_flag: if len(self.eye_track_dic[object]) > 0: self.eye_track_dic[object].append( self.eye_track_dic[object][-1]) else: self.eye_track_dic[object].append([]) # print "no positions!" # print self.eye_track_dic def draw_eye_tracking(self, clean_flag=False): media_time = self.player.position() for k in self.elements: v = self.audience_eye_tracking_dic[k] eye_tracking_window_index = int(media_time / self.eye_track_window) if eye_tracking_window_index >= len(self.eye_track_dic[k]) \ or len(self.eye_track_dic[k][eye_tracking_window_index]) < 3: continue v['pos'] = self.eye_track_dic[k][eye_tracking_window_index][0:2] v['rad'] = self.eye_track_dic[k][eye_tracking_window_index][2] v['lines'] = [] if len(v['pos']) == 2: for line_num in range( int(self.trial_lapse / self.eye_track_window)): if eye_tracking_window_index - line_num - 1 >= 0 and len( self.eye_track_dic[k][eye_tracking_window_index - line_num - 1]) == 3: v['lines'].append([ self.eye_track_dic[k][eye_tracking_window_index - line_num - 1], self.eye_track_dic[k][eye_tracking_window_index - line_num] ]) self.draw_dot_line(v, k) ##################### eye tracking ##################### def open_timeline(self): home = str(Path.home()) filename, _ = QtWidgets.QFileDialog.getOpenFileName( self, "Open TL", home) if not filename: return self.tldata = pandas.read_excel(str(filename)) self.tldata = self.tldata.as_matrix() self.makeArr(self.tldata) self.loaded = 1 self.update() self.randArr = np.random.randint(0, 256, size=(3, 15)) def makeArr(self, tldata): startX = 12.0 pixLength = 1168.0 self.rows, self.cols = self.tldata.shape dim = (self.rows, 6) self.tldata = np.concatenate((self.tldata, np.zeros((dim))), axis=1) #start_millisec self.tldata[:, 2] = self.tldata[:, 0] * 1000.0 #end_millisec self.tldata[:, 3] = self.tldata[:, 1] * 1000.0 #diff_millisec self.tldata[:, 4] = self.tldata[:, 3] - self.tldata[:, 2] #X1 position self.tldata[:, 5] = startX + (self.tldata[:, 2] / self.player.duration()) * pixLength #X2 position self.tldata[:, 6] = self.tldata[:, 5] + ( self.tldata[:, 4] / self.player.duration()) * pixLength #width in pixels self.tldata[:, 7] = self.tldata[:, 6] - self.tldata[:, 5] def paintEvent(self, e): if self.loaded == 1: qp = QtGui.QPainter() qp.begin(self) self.colorize(qp) qp.end() def colorize(self, qp): Y = 700 #print("tl loaded:", self.tl_loaded) for i in range(self.rows): k = i % 15 qp.fillRect( QtCore.QRectF(self.tldata[i, 6], Y, self.tldata[i, 7], 5), QtGui.QColor(self.randArr[0, k], self.randArr[1, k], self.randArr[2, k]))
class VideoSortApp(QMainWindow, Ui_MainWindow, QWidget): def __init__(self): super(VideoSortApp, self).__init__() self.setupUi(self) self.filename = None self.directory = None self.sort.setEnabled(False) self.fileOpen.clicked.connect(self.fileDialog) self.dirOpen.clicked.connect(self.folderDialog) self.sort.clicked.connect(self.sortVideo) self.results.setViewMode(self.results.IconMode) self.results.setResizeMode(self.results.Adjust) self.features = [] self.sorted = None #player properties self.player = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.playlist = QMediaPlaylist(self.player) self.videoItem = QGraphicsVideoItem() self.videoItem.setSize(QtCore.QSizeF(640, 480)) scene = QGraphicsScene(self) scene.addItem(self.videoItem) self.graphicsView.setScene(scene) self.player.setVideoOutput(self.videoItem) self.graphicsView.resize(640,480) self.graphicsView.show() self.results.itemDoubleClicked.connect(self.seekVideo) self.videoLoaded = False def sizeHint(self): return QtCore.QSize(640,480) def fileDialog(self): dialog = QFileDialog() if dialog.getOpenFileName: self.filename = dialog.getOpenFileName()[0] self.sort.setEnabled(True) def folderDialog(self): dialog = QFileDialog() if dialog.getExistingDirectory: self.directory = dialog.getExistingDirectory() self.sort.setEnabled(True) def sortVideo(self): dialog = QFileDialog() folder = dialog.getExistingDirectory(self, 'Select output directory for thumbnail images') if folder: if self.filename: self.getThread = VideoSort(self.filename, folder, 'frame') #self.results.setIconSize(QtCore.QSize(self.getThread.thumbInfo['resolution'][0], self.getThread.thumbInfo['resolution'][1])) #slot self.getThread.resultsSignal.connect(self.setFeatures) self.getThread.start() self.player.setMedia(QMediaContent(QtCore.QUrl.fromLocalFile(self.filename))) self.currentMedia = self.filename if self.directory: formatList = ['.mp4', '.mov', '.mkv', '.avi'] for dirname, dirnames, filenames in os.walk(self.directory): supportedFiles = [os.path.abspath(os.path.join(dirname, path)) for path in filenames if os.path.splitext(path)[1] in formatList] for filename in supportedFiles: self.getThread = VideoSort(filename, folder, os.path.splitext(filename.split('/')[-1])[0]) self.getThread.resultsSignal.connect(self.setFeatures) self.getThread.start() self.player.setMedia(QMediaContent(QtCore.QUrl.fromLocalFile(filename))) #Just set the last file as the current file self.player.setMedia(QMediaContent(QtCore.QUrl.fromLocalFile(filename))) self.currentMedia = filename def setFeatures(self, features): for feature in features: self.features.append(feature) self.hue.toggled.connect(self.displayResults) self.saturation.toggled.connect(self.displayResults) self.contours.toggled.connect(self.displayResults) def displayResults(self): self.results.clear() if self.hue.isChecked(): sortedFeatures = sorted(self.features, key=lambda res: res['hue']['std'], reverse=False) self.sorted = True if self.saturation.isChecked(): sortedFeatures = sorted(self.features, key=lambda res: res['sat']['std'], reverse=False) self.sorted = True if self.contours.isChecked(): sortedFeatures = sorted(self.features, key=lambda res: res['contours']['area'], reverse=False) self.sorted = True if self.sorted: for feature in sortedFeatures: icon = QtGui.QIcon(feature['thumbnail']) item = VideoListItem(icon, feature) self.results.addItem(item) def seekVideo(self, Qitem): #Need to write a callback function to only seek once player is loaded - provide loading media graphic or progress bar self.player.stop() print self.player.mediaStatus() if Qitem.feature['video'] != self.currentMedia: self.player.setMedia(QMediaContent(QtCore.QUrl.fromLocalFile(Qitem.feature['video']))) self.videoLoadProgress(self.player) self.currentMedia = Qitem.feature['video'] else: self.videoLoaded = True if self.videoLoaded: self.player.setPosition(Qitem.feature['milliseconds']) self.player.play() else: #set up progress bar here, or loading text def videoLoadProgress(self, QMediaPlayerObject): self.videoStatus = VideoLoadStatus(QMediaPlayerObject) self.videoStatus.videoLoaded.connect(self.getVideoStatus) def getVideoStatus(self, status): self.status = status
class 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 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 QmyMainWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) #调用父类构造函数,创建窗体 self.ui = Ui_MainWindow() #创建UI对象 self.ui.setupUi(self) #构造UI界面 self.player = QMediaPlayer(self) #创建视频播放器 self.player.setNotifyInterval(1000) #信息更新周期, ms scene = QGraphicsScene(self) self.ui.graphicsView.setScene(scene) self.videoItem = QGraphicsVideoItem() #视频显示画面 self.videoItem.setSize(QSizeF(320, 220)) self.videoItem.setFlag(QGraphicsItem.ItemIsMovable) self.videoItem.setFlag(QGraphicsItem.ItemIsSelectable) self.videoItem.setFlag(QGraphicsItem.ItemIsFocusable) scene.addItem(self.videoItem) self.player.setVideoOutput(self.videoItem) #设置视频显示图形项 self.textItem = QGraphicsTextItem("面朝大海,春暖花开") #弹幕文字 font = self.textItem.font() font.setPointSize(20) self.textItem.setFont(font) self.textItem.setDefaultTextColor(Qt.red) self.textItem.setPos(100, 220) self.textItem.setFlag(QGraphicsItem.ItemIsMovable) self.textItem.setFlag(QGraphicsItem.ItemIsSelectable) self.textItem.setFlag(QGraphicsItem.ItemIsFocusable) scene.addItem(self.textItem) self.ui.btnText.setCheckable(True) #弹幕文字按钮 self.ui.btnText.setChecked(True) self.__duration = "" self.__curPos = "" self.player.stateChanged.connect(self.do_stateChanged) self.player.positionChanged.connect(self.do_positionChanged) self.player.durationChanged.connect(self.do_durationChanged) ## ==============自定义功能函数======================== ## ==============event处理函数========================== def closeEvent(self, event): #窗体关闭时 # 窗口关闭时不能自动停止播放,需手动停止 if (self.player.state() == QMediaPlayer.PlayingState): self.player.stop() ## ==========由connectSlotsByName()自动连接的槽函数============ @pyqtSlot() ##打开文件 def on_btnOpen_clicked(self): curPath = QDir.currentPath() #获取系统当前目录 ## curPath=os.getcwd() title = "选择视频文件" filt = "视频文件(*.wmv *.avi);;所有文件(*.*)" fileName, flt = QFileDialog.getOpenFileName(self, title, curPath, filt) if (fileName == ""): return fileInfo = QFileInfo(fileName) baseName = fileInfo.fileName() ## baseName=os.path.basename(fileName) self.ui.LabCurMedia.setText(baseName) curPath = fileInfo.absolutePath() QDir.setCurrent(curPath) #重设当前目录 media = QMediaContent(QUrl.fromLocalFile(fileName)) self.player.setMedia(media) #设置播放文件 self.player.play() @pyqtSlot() ##播放 def on_btnPlay_clicked(self): self.player.play() @pyqtSlot() ##暂停 def on_btnPause_clicked(self): self.player.pause() @pyqtSlot() ##停止 def on_btnStop_clicked(self): self.player.stop() @pyqtSlot() ##全屏 def on_btnFullScreen_clicked(self): self.videoWidget.setFullScreen(True) @pyqtSlot() ##静音按钮 def on_btnSound_clicked(self): mute = self.player.isMuted() self.player.setMuted(not mute) if mute: self.ui.btnSound.setIcon(QIcon(":/icons/images/volumn.bmp")) else: self.ui.btnSound.setIcon(QIcon(":/icons/images/mute.bmp")) @pyqtSlot(int) ##音量调节 def on_sliderVolumn_valueChanged(self, value): self.player.setVolume(value) @pyqtSlot(int) ##播放进度调节 def on_sliderPosition_valueChanged(self, value): self.player.setPosition(value) @pyqtSlot() ##放大 def on_btnZoomIn_clicked(self): sc = self.videoItem.scale() self.videoItem.setScale(sc + 0.1) @pyqtSlot() ##缩小 def on_btnZoomOut_clicked(self): sc = self.videoItem.scale() self.videoItem.setScale(sc - 0.1) @pyqtSlot(bool) ##弹幕 def on_btnText_clicked(self, checked): self.textItem.setVisible(checked) ## =============自定义槽函数=============================== def do_stateChanged(self, state): isPlaying = (state == QMediaPlayer.PlayingState) self.ui.btnPlay.setEnabled(not isPlaying) self.ui.btnPause.setEnabled(isPlaying) self.ui.btnStop.setEnabled(isPlaying) def do_durationChanged(self, duration): self.ui.sliderPosition.setMaximum(duration) secs = duration / 1000 #秒 mins = secs / 60 #分钟 secs = secs % 60 #余数秒 self.__duration = "%d:%d" % (mins, secs) self.ui.LabRatio.setText(self.__curPos + "/" + self.__duration) def do_positionChanged(self, position): if (self.ui.sliderPosition.isSliderDown()): return #如果正在拖动滑条,退出 self.ui.sliderPosition.setSliderPosition(position) secs = position / 1000 #秒 mins = secs / 60 #分钟 secs = secs % 60 #余数秒 self.__curPos = "%d:%d" % (mins, secs) self.ui.LabRatio.setText(self.__curPos + "/" + self.__duration)
class VideoScene(QGraphicsScene): regionSelected = Signal(QRect) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.videoItem = QGraphicsVideoItem() self.videoItem.setPos(0, 0) self.videoItem.nativeSizeChanged.connect(self.videoSizeChanged) self.addItem(self.videoItem) self.rectangle = QGraphicsRectItem() self.rectangle.setPen(QColor(0, 122, 217)) self.addItem(self.rectangle) def videoSizeChanged(self, size: QSizeF): logging.debug("%s", size) if not size.isEmpty(): self.videoItem.setSize(size) self.setSceneRect(self.videoItem.boundingRect()) self.clearSelection() def clearSelection(self) -> None: self.rectangle.setRect(QRectF()) self.regionSelected.emit(self.selection) @property def selection(self) -> QRect: return self.rectangle.rect().toRect() @staticmethod def coerceInside(point: QPointF, rect: QRectF): return QPointF( min(max(point.x(), rect.left()), rect.right()), min(max(point.y(), rect.top()), rect.bottom()), ) def coerceInsideVideo(self, point: QPointF): return self.coerceInside(point, self.videoItem.boundingRect()) def mousePressEvent(self, event: QGraphicsSceneMouseEvent) -> None: self.startPos = self.coerceInsideVideo(event.scenePos()) return super().mousePressEvent(event) def mouseMoveEvent(self, event: QGraphicsSceneMouseEvent) -> None: endPos = self.coerceInsideVideo(event.scenePos()) self.rectangle.setRect(QRectF(self.startPos, endPos).normalized()) return super().mouseMoveEvent(event) def mouseReleaseEvent(self, event: QGraphicsSceneMouseEvent) -> None: logging.info("Selection: %s", self.selection) super().mouseReleaseEvent(event) self.regionSelected.emit(self.selection) def paintGrid(self, painter: QPainter, rect: QRectF, gridSize: int): left, top, right, bottom = rect.getCoords() x_min = (int(left - 1) // gridSize + 1) * gridSize y_min = (int(top - 1) // gridSize + 1) * gridSize x_max = (int(right) // gridSize) * gridSize y_max = (int(bottom) // gridSize) * gridSize # logging.debug( # "x=(%s<=%s..%s<=%s) y=(%s<=%s..%s<=%s)", # *(left, x_min, x_max, right), # *(top, y_min, y_max, bottom) # ) painter.setPen(QPen(Qt.gray, 2)) painter.drawLines(QLineF(0, top, 0, bottom), QLineF(left, 0, right, 0)) painter.setPen(QPen(Qt.gray, 1)) painter.drawLines( QLineF(x, top, x, bottom) for x in range(x_min, x_max + 1, gridSize) if x) painter.drawLines( QLineF(left, y, right, y) for y in range(y_min, y_max + 1, gridSize) if y) def drawBackground(self, painter: QPainter, rect: QRectF) -> None: super().drawBackground(painter, rect) self.paintGrid(painter, rect, 20)
class VideoPlayer(QWidget): """ Arguments --------- parent: QWidget, the parent widget of VideoPlayer display_status: bool, default False, will show the status of the media player in the gui """ def __init__(self, parent=None, display_status=False): super(VideoPlayer, self).__init__(parent) self.display_status = display_status self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.videoItem = QGraphicsVideoItem() scene = QGraphicsScene(self) graphicsView = QGraphicsView(scene) scene.addItem(self.videoItem) self.playButton = QPushButton() self.playButton.setEnabled(False) self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay)) self.playButton.clicked.connect(self.play) self.positionSlider = QSlider(Qt.Horizontal) self.positionSlider.setRange(0, 0) self.positionSlider.sliderMoved.connect(self.setPosition) if self.display_status: self.status_mapping = { QMediaPlayer.UnknownMediaStatus: "UnknownMediaStatus", QMediaPlayer.NoMedia: "NoMedia", QMediaPlayer.LoadingMedia: "LoadingMedia", QMediaPlayer.LoadedMedia: "LoadedMedia", QMediaPlayer.StalledMedia: "StalledMedia", QMediaPlayer.BufferingMedia: "BufferingMedia", QMediaPlayer.BufferedMedia: "BufferedMedia", QMediaPlayer.EndOfMedia: "EndOfMedia", QMediaPlayer.InvalidMedia: "InvalidMedia" } self.statusText = QPlainTextEdit() self.statusText.setReadOnly(True) self.statusText.setFixedHeight(25) self.statusText.setFixedWidth(150) self.mediaPlayer.mediaStatusChanged.connect(self.mediaStatusChanged) controlLayout = QHBoxLayout() controlLayout.setContentsMargins(0, 0, 0, 0) controlLayout.addWidget(self.playButton) controlLayout.addWidget(self.positionSlider) if self.display_status: controlLayout.addWidget(self.statusText) layout = QVBoxLayout() layout.addWidget(graphicsView) layout.addLayout(controlLayout) self.setFixedWidth(WIDTH + WIGGLE) self.setLayout(layout) self.mediaPlayer.setVideoOutput(self.videoItem) self.mediaPlayer.stateChanged.connect(self.mediaStateChanged) self.mediaPlayer.positionChanged.connect(self.positionChanged) self.mediaPlayer.durationChanged.connect(self.durationChanged) def openFile(self, fileName): if fileName != '' or fileName is not None: self.mediaPlayer.setMedia( QMediaContent(QUrl.fromLocalFile(fileName))) # set resolution res_orig = get_video_resolution(fileName) self.aspect_ratio = float(res_orig[0]) / res_orig[1] self.videoItem.setSize(QSizeF(WIDTH, WIDTH / self.aspect_ratio)) self.setFixedHeight(WIDTH / self.aspect_ratio + 2*WIGGLE) self.playButton.setEnabled(True) # trick to show screenshot of the first frame of video self.mediaPlayer.play() self.mediaPlayer.pause() def play(self): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.mediaPlayer.pause() else: self.mediaPlayer.play() def mediaStateChanged(self, state): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.playButton.setIcon( self.style().standardIcon(QStyle.SP_MediaPause)) else: self.playButton.setIcon( self.style().standardIcon(QStyle.SP_MediaPlay)) def mediaStatusChanged(self, status): self.statusText.setPlaceholderText(self.status_mapping[status]) def positionChanged(self, position): self.positionSlider.setValue(position) print self.positionSlider.value() # if position slider has reached the end, let's stop the video if self.positionSlider.value() >= self.positionSlider.maximum() - 1: self.mediaPlayer.stop() # play/pause hack to show the first frame of video self.mediaPlayer.play() self.mediaPlayer.pause() def durationChanged(self, duration): self.positionSlider.setRange(0, duration) def setPosition(self, position): self.mediaPlayer.setPosition(position)
class VideoPlayer(QWidget): def __init__(self, parent=None): super(VideoPlayer, self).__init__(parent) self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.videoItem = QGraphicsVideoItem() self.videoItem.setSize(QSizeF(640, 480)) scene = QGraphicsScene(self) graphicsView = QGraphicsView(scene) scene.addItem(self.videoItem) rotateSlider = QSlider(Qt.Horizontal) rotateSlider.setRange(-180, 180) rotateSlider.setValue(0) rotateSlider.valueChanged.connect(self.rotateVideo) openButton = QPushButton("Open...") openButton.clicked.connect(self.openFile) self.playButton = QPushButton() self.playButton.setEnabled(False) self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay)) self.playButton.clicked.connect(self.play) self.positionSlider = QSlider(Qt.Horizontal) self.positionSlider.setRange(0, 0) self.positionSlider.sliderMoved.connect(self.setPosition) controlLayout = QHBoxLayout() controlLayout.setContentsMargins(0, 0, 0, 0) controlLayout.addWidget(openButton) controlLayout.addWidget(self.playButton) controlLayout.addWidget(self.positionSlider) layout = QVBoxLayout() layout.addWidget(graphicsView) layout.addWidget(rotateSlider) layout.addLayout(controlLayout) self.setLayout(layout) self.mediaPlayer.setVideoOutput(self.videoItem) self.mediaPlayer.stateChanged.connect(self.mediaStateChanged) self.mediaPlayer.positionChanged.connect(self.positionChanged) self.mediaPlayer.durationChanged.connect(self.durationChanged) def sizeHint(self): return QSize(800, 600) def openFile(self): fileName, _ = QFileDialog.getOpenFileName(self, "Open Movie", QDir.homePath()) if fileName != '': self.mediaPlayer.setMedia( QMediaContent(QUrl.fromLocalFile(fileName))) self.playButton.setEnabled(True) def play(self): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.mediaPlayer.pause() else: self.mediaPlayer.play() def mediaStateChanged(self, state): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.playButton.setIcon(self.style().standardIcon( QStyle.SP_MediaPause)) else: self.playButton.setIcon(self.style().standardIcon( QStyle.SP_MediaPlay)) def positionChanged(self, position): self.positionSlider.setValue(position) def durationChanged(self, duration): self.positionSlider.setRange(0, duration) def setPosition(self, position): self.mediaPlayer.setPosition(position) def rotateVideo(self, angle): x = self.videoItem.boundingRect().width() / 2.0 y = self.videoItem.boundingRect().height() / 2.0 self.videoItem.setTransform(QTransform().translate( x, y).rotate(angle).translate(-x, -y))
class VideoShow(QtWidgets.QWidget): def __init__(self, parent=None): super().__init__() self.parent = parent self.setupUi(self) self.start() #self.turnOnOrOffButton(False) def start(self): self.toolButton.setEnabled(False) self.listStartTime = [] self.indexNextSub = 0 self.isEnableSub = False self.isEnableSub2 = False self.isOpenedVideo = False self.loadedPath = ['', '', ''] # video, sub1, sub2 self.isEngOrVieOrTwiceSubLabel = 3 self.buttonCtrlPressed = False self.skipTime = 500 # Tắt focus để bắt sự kiện button arrow !!! def setChildrenFocusPolicy(self, policy): def recursiveSetChildFocusPolicy(parentQWidget): for childQWidget in parentQWidget.findChildren(QWidget): childQWidget.setFocusPolicy(policy) recursiveSetChildFocusPolicy(childQWidget) recursiveSetChildFocusPolicy(self) def keyReleaseEvent(self, event): if event.key() == Qt.Key_Control: self.buttonCtrlPressed = False def keyPressEvent(self, event): #print(self.buttonCtrlPressed) self.notificationVideo.setText('') if event.key() == Qt.Key_Control: self.buttonCtrlPressed = True #print(self.isFullScreen()) if event.key() == Qt.Key_Escape and self.isFullScreen(): self.fullScreen() if event.key() == Qt.Key_Enter: if self.frameSlider.isHidden(): self.frameSlider.show() self.frameButton.show() else: self.frameSlider.hide() self.frameButton.hide() if event.key() == Qt.Key_Space: self.play() if event.key() == Qt.Key_Right: self.forwardVideo() if event.key() == Qt.Key_Left: self.backwardVideo() if event.key() == Qt.Key_Comma and not self.buttonCtrlPressed: self.backwardSub() if event.key() == Qt.Key_Period and not self.buttonCtrlPressed: self.forwardSub() if event.key() == Qt.Key_E: self.isEngOrVieOrTwiceSubLabel = 1 self.setLabelVieo(1) if event.key() == Qt.Key_V: self.isEngOrVieOrTwiceSubLabel = 2 self.setLabelVieo(2) if event.key() == Qt.Key_T: self.isEngOrVieOrTwiceSubLabel = 3 self.setLabelVieo(3) if event.key( ) == Qt.Key_S and not self.buttonCtrlPressed: # sử dụng thêm keyReleaseEvent để đánh dấu nút ctrl if self.labelVideo.isVisible(): self.labelVideo.setVisible(False) else: self.labelVideo.setVisible(True) if event.key() == Qt.Key_F: self.fullScreen() modifiers = QtWidgets.QApplication.keyboardModifiers() if modifiers == QtCore.Qt.ControlModifier and event.key( ) == Qt.Key_Comma: print('skip -%d' % self.skipTime) self.skipSub(-1) if modifiers == QtCore.Qt.ControlModifier and event.key( ) == Qt.Key_Period: print('skip +%d' % self.skipTime) self.skipSub(1) if modifiers == QtCore.Qt.ControlModifier and event.key() == Qt.Key_S: self.saveCoupleFromButtonEvent() # mouseMouve Event # def mouseMoveEvent(self, event): # if self.frameSlider.isHidden(): # self.frameSlider.show() # print('show frameslider') # QThread.sleep(3) # self.frameSlider.hide() # print('hide frameslider') def setLabelVieo(self, typeof): if self.labelVideo.text() != '': if self.indexNextSub != 0 or self.indexNextSub != len( self.listStartTime) - 1: text = self.listStartTime[self.indexNextSub - 1][0].text() else: text = self.listStartTime[self.indexNextSub][0].text() if typeof == 1 and self.isEnableSub: self.labelVideo.setText(text.split('\n')[0]) elif typeof == 2 and self.isEnableSub2: self.labelVideo.setText(text.split('\n')[1]) elif self.isEnableSub and self.isEnableSub2: self.labelVideo.setText(text) def turnOnOrOffSubVideoLabel(self): if self.labelVideo.isVisible(): self.labelVideo.setVisible(False) else: self.labelVideo.setVisible(True) def forwardVideo(self): pos = self.mediaPlayer.position() if self.isEnableSub: if self.indexNextSub >= 1: self.indexNextSub -= 1 self.grabIndexCurrent(pos + 10000, len(self.listStartTime) - 1, 1) self.mediaPlayer.setPosition(pos + 10000) def backwardVideo(self): pos = self.mediaPlayer.position() if self.isEnableSub: if self.indexNextSub < len(self.listStartTime) - 1: self.indexNextSub += 1 if pos > self.maxTimeVideo: pos = self.maxTimeVideo self.grabIndexCurrent(pos - 10000, 0, -1) self.mediaPlayer.setPosition(pos - 10000) def forwardSub(self): if self.isEnableSub: self.mediaPlayer.setPosition( self.listStartTime[self.indexNextSub][2]) self.setStatusScrollArea() def backwardSub(self): if self.isEnableSub and self.indexNextSub >= 2: self.indexNextSub -= 2 self.mediaPlayer.setPosition( self.listStartTime[self.indexNextSub][2]) self.setStatusScrollArea() def skipSub(self, direction): # if self.isEnableSub: # self.setStatusScrollArea() for item in self.listStartTime: item[2] += self.skipTime * direction item[3] += self.skipTime * direction self.notificationVideo.setText('skip %d' % (direction * self.skipTime)) def calculateTime(self, subRipTime): time = str(subRipTime).replace(',', ':') time = time.split(':') time = list(map(lambda x: int(x), time)) time = (time[0] * 3600 + time[1] * 60 + time[2]) * 1000 + time[3] return time def saveCoupleFromButtonEvent(self): if self.isEnableSub and self.isEnableSub2: checkbox = None if self.indexNextSub != 0: checkbox = self.listStartTime[self.indexNextSub - 1][0] else: checkbox = self.listStartTime[self.indexNextSub][0] if checkbox.isChecked(): checkbox.setChecked(False) else: checkbox.setChecked(True) self.saveCouple(checkbox) def saveCouple(self, checkbox): if self.isEnableSub and not self.actionOpenSub2.isEnabled(): text = checkbox.text() if text.find('\n') == -1: checkbox.setEnabled(False) QtWidgets.QMessageBox.information( None, 'WARNING', "Can't save with single sentence") return couple = text.split('\n') print(checkbox.isChecked()) if not checkbox.isChecked(): self.parent.parent.DictDB.delete('ENG', couple[0]) QtWidgets.QMessageBox.information(None, 'Notification', 'Couple was deleted !') else: result1 = self.parent.parent.DictDB.selectRowIDByEngOrVie( 'ENG', couple[0]) result2 = self.parent.parent.DictDB.selectRowIDByEngOrVie( 'VIE', couple[1]) if len(result1) == 0 and len(result2) == 0: self.parent.parent.DictDB.insert(couple[0], couple[1], 0) QtWidgets.QMessageBox.information(None, 'Notification', 'Couple was inserted !') else: QtWidgets.QMessageBox.information( None, 'WARNING', 'Couple already exist in revision') self.buttonCtrlPressed = False def eventSubCheckBox(self, checkbox): def event(): self.saveCouple(checkbox) return event def eventSubButton(self, time, index): # time tính theo milisecond def event(): self.mediaPlayer.setPosition(time) self.indexNextSub = index self.setStatusScrollArea() return event def enableCheckBoxsOrButtonScroll(self, index): if self.isEnableSub: for item in self.listStartTime: item[index].setEnabled(True) def loadSubToScroll(self, fileName): subs = pysrt.open(fileName) for index, value in enumerate(subs): horizontalLayoutScroll = QtWidgets.QHBoxLayout() checkbox = QtWidgets.QCheckBox(self.scrollAreaWidgetContents) checkbox.setObjectName('checkbox%s' % (index)) text = value.text.replace('\n', ' ').replace("\"", "''") checkbox.setText(text.replace('\xa0', ' ')) checkbox.setFixedHeight(50) checkbox.setFont(QtGui.QFont('Times New Roman', 10)) checkbox.clicked.connect(self.eventSubCheckBox(checkbox)) checkbox.setFocusPolicy(Qt.NoFocus) button = QtWidgets.QToolButton(self.scrollAreaWidgetContents) button.setObjectName('button%s' % (index)) button.setFixedHeight(20) icon = QtGui.QIcon() icon.addPixmap(QtGui.QPixmap("assets/access.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) button.setIcon(icon) button.setIconSize(QtCore.QSize(32, 32)) button.setFocusPolicy(Qt.NoFocus) checkbox.setEnabled(False) if not self.isOpenedVideo: button.setEnabled(False) startTime = self.calculateTime(value.start) endTime = self.calculateTime(value.end) button.clicked.connect(self.eventSubButton(startTime, index)) horizontalLayoutScroll.addWidget(checkbox, 0) horizontalLayoutScroll.addWidget(button, 10) horizontalLayoutScroll.setContentsMargins( 0, 0, 50, 0) # left, top, right, bottom self.verticalScroll.addLayout(horizontalLayoutScroll) self.listStartTime.append( [checkbox, button, startTime, endTime, value.start]) def LoadOtherSub(self, fileName): subs = pysrt.open(fileName) if subs[5].start == self.listStartTime[5][2] and subs[ 10].end == self.listStartTime[10][3]: for index, item in enumerate(self.listStartTime): while subs[0].start < item[4]: del subs[0] if subs[0].start == item[4]: text = subs[0].text.replace('\n', ' ').replace( '\xa0', ' ').replace("\"", "''") item[0].setText(item[0].text() + '\n' + text) del subs[0] self.actionOpenSub2.setEnabled(False) self.enableCheckBoxsOrButtonScroll(0) self.isEnableSub2 = True self.loadedPath[2] = fileName else: QtWidgets.QMessageBox.information( None, 'WARNING', 'Please choose correctly sub compatible with engsub') def clearLayout(self, layout): if layout is not None: while layout.count(): item = layout.takeAt(0) widget = item.widget() if widget is not None: widget.deleteLater() else: self.clearLayout(item.layout()) def closeEvent(self, event): reply = QtWidgets.QMessageBox.question(self, 'Message', "Are you sure to quit?", QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No) if reply == QtWidgets.QMessageBox.Yes: event.accept() self.mediaPlayer.stop() else: event.ignore() def reloadVideoAndSub(self): self.clearLayout(self.verticalScroll) #self.mediaPlayer.setMedia(QMediaPlayer.NoMedia) #self.mediaPlayer.destroyed() QMediaPlayer.stop(self.mediaPlayer) # init self.start() self.scrollArea.hide() self.actionOpenSub1.setEnabled(True) self.actionOpenSub2.setEnabled(False) print(len(self.listStartTime)) def turnOnOrOffButton(self, turn): buttons = [self.toolButton, self.toolButton_3, self.toolButton_4] map(lambda x: x.setEnabled(turn), buttons) def openVid(self, fileName): self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile(fileName))) self.toolButton.setEnabled(True) self.enableCheckBoxsOrButtonScroll(1) self.isOpenedVideo = True self.loadedPath[0] = fileName #self.turnOnOrOffButton(True) self.play() def openEngSub(self, fileName): self.loadSubToScroll(fileName) self.scrollArea.show() self.isEnableSub = True self.actionOpenSub2.setEnabled(True) self.actionOpenSub1.setEnabled(False) self.loadedPath[1] = fileName def openFile(self, title): def open_file(): choose = -1 dialog = QtWidgets.QFileDialog() extension = '' if title == 'Open Video': extension = 'Videos (*.mkv *.mp4 *.mpg)' choose = 1 elif title == 'Open Eng Sub': extension = 'SRT (*.srt)' choose = 2 elif title == 'Open Viewed Video': pass else: extension = 'SRT (*.srt)' choose = 3 #dialog.setDefaultSuffix(".srt") fileName, _ = dialog.getOpenFileName(None, title, QDir.homePath(), extension) name = fileName.lower() if choose == 2: # quy ước loại sub sẽ đặt tên ở đuôi !!! if name[len(name) - 7:len(name) - 4] != 'eng': QtWidgets.QMessageBox.information( None, 'WARNING', 'Please choose correctly sub with format *eng.srt') return elif choose == 3: if name[len(name) - 7:len(name) - 4] != 'vie': QtWidgets.QMessageBox.information( None, 'WARNING', 'Please choose correctly sub with format *vie.srt') return if fileName != '': #self.loadSubToScroll() if title == 'Open Video': self.openVid(fileName) elif title == 'Open Eng Sub': self.openEngSub(fileName) else: self.LoadOtherSub(fileName) loaded = True for p in self.loadedPath: if p == '': loaded = False if loaded: with open('history.txt', 'w') as file: file.writelines(','.join(self.loadedPath)) return open_file def openViewedVideo(self): with open('history.txt', 'r') as file: paths = file.readlines()[0].split(',') self.openVid(paths[0]) self.openEngSub(paths[1]) self.LoadOtherSub(paths[2]) def play(self): icon = QtGui.QIcon() if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.mediaPlayer.pause() icon.addPixmap(QtGui.QPixmap("assets/pause.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.toolButton.setIcon(icon) else: icon.addPixmap(QtGui.QPixmap("assets/play.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.toolButton.setIcon(icon) self.mediaPlayer.play() def scrollToSub(self, curHeight, maxHeight): # dùng hệ thức chéo để tính tỉ lệ ! self.maxButtonPos = self.listStartTime[-1][1].y() pos = int(float(curHeight / self.maxButtonPos) * maxHeight) #print(pos, curHeight, maxHeight) self.scrollArea.verticalScrollBar().setValue(pos) # hàm sự kiện này có đối số position là mặc định !!! def setTextCheckBox(self, checkbox, color, size, italic_): checkbox.setStyleSheet('color: %s' % (color)) checkbox.setFont(QtGui.QFont('Times New Roman', size, italic=italic_)) def setStatusScrollArea(self): timeSub = self.listStartTime[self.indexNextSub] self.setTextCheckBox(timeSub[0], 'green', 15, True) if self.oldIndexSub != 0: self.setTextCheckBox(self.listStartTime[self.oldIndexSub][0], 'black', 10, False) self.scrollToSub(timeSub[1].y(), self.scrollArea.verticalScrollBar().maximum()) text = timeSub[0].text() if self.isEngOrVieOrTwiceSubLabel == 1: self.labelVideo.setText(text.split('\n')[0]) elif self.isEngOrVieOrTwiceSubLabel == 2: self.labelVideo.setText(text.split('\n')[1]) else: self.labelVideo.setText(text) self.oldIndexSub = self.indexNextSub if self.indexNextSub < len(self.listStartTime) - 1: self.indexNextSub += 1 def durationChanged(self, duration): self.positionSlider.setRange(0, duration) self.maxTimeVideo = duration self.labelDurationTime.setText(self.formatTimeToHMS(duration)) def positionChanged(self, position): self.positionSlider.setValue(position) self.labelCurTime.setText(self.formatTimeToHMS(position)) if self.isEnableSub: start = self.listStartTime[self.indexNextSub][2] end = self.listStartTime[self.indexNextSub][3] if position >= start and position <= end: self.setStatusScrollArea() def grabIndexCurrent(self, position, stopIndex, step): indexCur = self.indexNextSub for i in range(indexCur, stopIndex, step): start = self.listStartTime[i][2] end = self.listStartTime[i][3] if position >= start and position <= end: self.indexNextSub = i break if step == 1 and position >= end and position <= self.listStartTime[ i + 1][2]: self.indexNextSub = i + 1 break elif step == -1 and position <= start and position >= self.listStartTime[ i - 1][2]: self.indexNextSub = i break if indexCur == self.indexNextSub: if step == 1: self.indexNextSub = len(self.listStartTime) - 1 else: self.indexNextSub = 1 #print(self.indexNextSub) def formatTime(self, time): if len(time) == 1: return '0' + time return time def formatTimeToHMS(self, time): time = time / 1000 hour = int(time / 3600) minute = int((time - 3600 * hour) / 60) second = int(time - 3600 * hour - minute * 60) return '%s:%s:%s' % (self.formatTime( str(hour)), self.formatTime( str(minute)), self.formatTime(str(second))) # sliderMoved có sẵn tham số position cho slider để tùy chỉnh video !!! def sliderMoved(self, position): self.mediaPlayer.setPosition(position) def setSCrollbar(self, number): def setScroll(): #self.scrollArea.scrollContentsBy(0, number) #self.scrollAreaWidgetContents.scroll(number) vbar = self.scrollArea.verticalScrollBar() #print(vbar.maximum()) vbar.setValue(number) return setScroll def fullScreen(self): icon = QtGui.QIcon() if self.isFullScreen(): icon.addPixmap(QtGui.QPixmap("assets/fullscreen.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.toolButtonFullScreen.setIcon(icon) self.verticalLayout.setContentsMargins(9, 9, 9, 9) if self.isEnableSub: self.scrollArea.show() self.menubar.show() self.frameSlider.show() self.frameButton.show() self.showNormal() self.videoItem.setSize(QSizeF(600, 400)) #self.graphicsView.fitInView(QRectF(-400, -400, 400, 400), Qt.KeepAspectRatio) #self.graphicsView.setMaximumSize(QSize(600, 400)) #self.graphicsView.setAlignment(Qt.AlignCenter) self.labelVideo.hide() else: icon.addPixmap(QtGui.QPixmap("assets/minimize.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.toolButtonFullScreen.setIcon(icon) self.verticalLayout.setContentsMargins(0, 0, 0, 0) if self.isEnableSub: self.scrollArea.hide() self.menubar.hide() self.frameSlider.hide() self.frameButton.hide() self.showFullScreen() self.videoItem.setSize(QSizeF(self.width() - 1, self.height() - 2)) self.labelVideo.show() def setupUi(self, Form): self.sizeMonitor = [GetSystemMetrics(0), GetSystemMetrics(1)] self.setMouseTracking(True) self.form = Form Form.setObjectName("Form") Form.resize(631, 406) self.oldHighLine = None self.oldIndexSub = 0 self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.mediaPlayer.positionChanged.connect( self.positionChanged) # bắt frame video thay đổi self.mediaPlayer.durationChanged.connect( self.durationChanged) # bắt thời lượng video # Hàm này chỉ chạy có 1 lần !!! # Create Slider tạo thanh trượt video #self.positionSlider = QSlider(Qt.Horizontal) self.positionSlider = Slider(Qt.Horizontal) # truyền đối số Qt.Horizontal không dùng hàm __init__ nó sẽ kế thừa trực tiếp từ Horizontal # nếu dùng hàm __init__ nó sẽ ko kế thừa được mà chỉ tham chiếu đến lớp horizontal !!! self.positionSlider.parent = self self.positionSlider.setRange(0, 0) self.positionSlider.sliderMoved.connect(self.sliderMoved) # set event notify 500 millisecond QMediaObject.setNotifyInterval(self.mediaPlayer, 500) # Create Menubar self.menubar = QtWidgets.QMenuBar(Form) self.menubar.setFixedHeight(25) self.menuOpen = QtWidgets.QMenu(self.menubar) self.menuOpen.setObjectName('menuOpen') self.menuOption = QtWidgets.QMenu(self.menubar) self.menuOption.setObjectName('menuOption') self.actionReload = QtWidgets.QAction(Form) self.actionReload.setObjectName('actionReload') self.actionReload.triggered.connect(self.reloadVideoAndSub) self.menuOption.addAction(self.actionReload) self.actionOpenVideo = QtWidgets.QAction(Form) self.actionOpenVideo.setObjectName('openvideo') self.actionOpenSub1 = QtWidgets.QAction(Form) self.actionOpenSub1.setObjectName('openSub1') self.actionOpenSub1.triggered.connect(self.openFile('Open Eng Sub')) self.actionOpenSub2 = QtWidgets.QAction(Form) self.actionOpenSub2.setObjectName('openSub2') self.actionOpenSub2.triggered.connect(self.openFile('Open Vie Sub')) self.actionOpenViewedVideo = QtWidgets.QAction(Form) self.actionOpenViewedVideo.triggered.connect(self.openViewedVideo) self.menuOpen.addAction(self.actionOpenVideo) self.menuOpen.addAction(self.actionOpenSub1) self.menuOpen.addAction(self.actionOpenSub2) self.menuOpen.addAction(self.actionOpenViewedVideo) self.actionOpenVideo.triggered.connect(self.openFile('Open Video')) self.menubar.addAction(self.menuOpen.menuAction()) self.menubar.addAction(self.menuOption.menuAction()) self.actionOpenSub2.setEnabled(False) self.verticalLayout = QtWidgets.QVBoxLayout(Form) self.verticalLayout.setObjectName("verticalLayout") self.horizontalLayout = QtWidgets.QHBoxLayout() self.horizontalLayout.setObjectName("horizontalLayout") # create gridlayout contain scrollarea # self.gridLayout = QtWidgets.QGridLayout(Form) # self.gridLayout.setObjectName("gridLayout") # create scrollarea self.scrollArea = QtWidgets.QScrollArea(Form) self.scrollArea.setObjectName("scrollArea") self.scrollArea.setWidgetResizable(True) self.scrollArea.setMinimumSize(300, 400) self.scrollAreaWidgetContents = QtWidgets.QWidget() self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 430, 319)) self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents") self.scrollArea.setWidget(self.scrollAreaWidgetContents) # create verticalscroll # chú ý lớp cha là scroll widget content self.verticalScroll = QtWidgets.QVBoxLayout( self.scrollAreaWidgetContents) # self.gridLayout.addWidget(self.scrollArea) self.verticalLayout.addWidget(self.menubar, 0) scene = QGraphicsScene(self) self.graphicsView = QGraphicsView( scene) # dùng widget graphicsview mới overlay lable lên được !!! self.videoItem = QGraphicsVideoItem() self.videoItem.setSize(QSizeF(600, 400)) #self.graphicsView.setStyleSheet("background-color:black;") # dùng palette (bảng màu) riêng cho widget nên không ảnh hưởng đến labelvideo khi ghi đè lên p = self.graphicsView.palette() p.setColor(self.graphicsView.backgroundRole(), Qt.black) self.graphicsView.setPalette(p) scene.addItem(self.videoItem) self.horizontalLayout.addWidget(self.graphicsView) self.mediaPlayer.setVideoOutput(self.videoItem) # add label for videowidget represent subtitle self.labelVideo = QtWidgets.QLabel(self.graphicsView) self.labelVideo.setObjectName('labelVideo') self.labelVideo.setText('') self.labelVideo.setStyleSheet( "QLabel {font-size: 20px; opacity:1; color:white}") self.labelVideo.setFixedWidth(500) self.labelVideo.setFixedHeight(200) self.labelVideo.setAlignment(Qt.AlignCenter) self.labelVideo.setWordWrap(True) self.labelVideo.move(int(self.sizeMonitor[0] / 2 - 200), int(self.sizeMonitor[1] * 5 / 7)) #print(self.labelVideo.x(), self.labelVideo.y()) #self.labelVideo.raise_() #self.videoWidget.raise_() self.notificationVideo = QtWidgets.QLabel(self.graphicsView) self.notificationVideo.setObjectName('notificationVideo') self.notificationVideo.setText('') self.notificationVideo.setStyleSheet( "QLabel {font-size: 20px; opacity:1; color:white}") self.notificationVideo.setFixedWidth(500) self.notificationVideo.setFixedHeight(200) self.notificationVideo.setAlignment(Qt.AlignCenter) self.notificationVideo.setWordWrap(True) self.notificationVideo.move(int(self.sizeMonitor[0] / 2 + 200), int(self.sizeMonitor[1] * 2 / 7)) self.horizontalLayout.addWidget(self.scrollArea) self.verticalLayout.addLayout(self.horizontalLayout, 10) # cho stretch widget là 100% tức sẽ chiếm toàn bộ diện tích trong layout !!! # những widget khác cho 0% stretch # create layoutSlider self.horizontalLayoutSlider = QtWidgets.QHBoxLayout() self.horizontalLayoutSlider.setObjectName("horizontalLayoutSlider") self.labelCurTime = QtWidgets.QLabel(Form) self.labelCurTime.setObjectName('labelCurTime') self.labelCurTime.setText('00:00') self.labelDurationTime = QtWidgets.QLabel(Form) self.labelDurationTime.setText('NaN') self.labelDurationTime.setObjectName('labelDurationTime') self.horizontalLayoutSlider.addWidget(self.labelCurTime) self.horizontalLayoutSlider.addWidget(self.positionSlider) self.horizontalLayoutSlider.addWidget(self.labelDurationTime) #self.verticalLayout.addLayout(self.horizontalLayoutSlider,0) # Layout không thể hide được nên sẽ dùng frame (kế thừa từ widget) setlayout để hide nó self.frameSlider = QtWidgets.QFrame() self.frameSlider.setLayout(self.horizontalLayoutSlider) self.verticalLayout.addWidget(self.frameSlider, 0) self.horizontalLayout_2 = QtWidgets.QHBoxLayout() self.horizontalLayout_2.setObjectName("horizontalLayout_2") #self.verticalLayout.addLayout(self.horizontalLayout_2) self.toolButton = QtWidgets.QToolButton(Form) icon = QtGui.QIcon() icon.addPixmap(QtGui.QPixmap("assets/play.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.toolButton.setIcon(icon) self.toolButton.setIconSize(QtCore.QSize(32, 32)) self.toolButton.setObjectName("toolButton") # Event play self.toolButton.clicked.connect(self.play) self.horizontalLayout_2.addWidget(self.toolButton) self.toolButton_3 = QtWidgets.QToolButton(Form) icon1 = QtGui.QIcon() icon1.addPixmap(QtGui.QPixmap("assets/previous.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.toolButton_3.setIcon(icon1) self.toolButton_3.setIconSize(QtCore.QSize(32, 32)) self.toolButton_3.setObjectName("toolButton_3") self.toolButton_3.clicked.connect(self.backwardVideo) self.horizontalLayout_2.addWidget(self.toolButton_3) self.toolButton_4 = QtWidgets.QToolButton(Form) icon2 = QtGui.QIcon() icon2.addPixmap(QtGui.QPixmap("assets/next.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.toolButton_4.setIcon(icon2) self.toolButton_4.setIconSize(QtCore.QSize(32, 32)) self.toolButton_4.setObjectName("toolButton_4") self.toolButton_4.clicked.connect(self.forwardVideo) self.horizontalLayout_2.addWidget(self.toolButton_4) #self.verticalLayout.addLayout(self.horizontalLayout_2,0) self.toolButtonFullScreen = QtWidgets.QToolButton(Form) self.toolButtonFullScreen.setObjectName('toolButtonFullScreen') icon3 = QtGui.QIcon() icon3.addPixmap(QtGui.QPixmap('assets/fullscreen.png'), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.toolButtonFullScreen.setIcon(icon3) self.toolButtonFullScreen.setIconSize(QtCore.QSize(32, 32)) self.horizontalLayout_2.addWidget(self.toolButtonFullScreen) self.toolButtonFullScreen.clicked.connect(self.fullScreen) # self.toolButton_3.clicked.connect(self.setSCrollbar(30)) # self.toolButton_4.clicked.connect(self.setSCrollbar(90)) self.frameButton = QtWidgets.QFrame() self.frameButton.setLayout(self.horizontalLayout_2) self.verticalLayout.addWidget(self.frameButton, 0) # turn on mousemove tracking for videowidget !!! #self.videoWidget.setMouseTracking(True) # tắt mục tiêu tập trung để nhật sự kiện arrow button self.setChildrenFocusPolicy(Qt.NoFocus) self.scrollArea.setFocusPolicy(Qt.NoFocus) # setcontentsmargins cho verticalLayout Tổng chứ ko phải cho Form !!! #self.verticalLayout.setContentsMargins(0,0,0,0) self.scrollArea.hide() self.retranslateUi(Form) QtCore.QMetaObject.connectSlotsByName(Form) def retranslateUi(self, Form): _translate = QtCore.QCoreApplication.translate Form.setWindowTitle(_translate("Form", "Study Film")) self.toolButton.setText(_translate("Form", "...")) self.toolButton_3.setText(_translate("Form", "...")) self.toolButton_4.setText(_translate("Form", "...")) self.menuOpen.setTitle(_translate("Form", "Open")) self.menuOption.setTitle(_translate("Form", "Option")) self.actionReload.setText(_translate("Form", 'Reload')) self.actionOpenVideo.setText(_translate("Form", 'Open video')) self.actionOpenSub1.setText(_translate("Form", 'Open Eng Sub')) self.actionOpenSub2.setText(_translate("Form", 'Open Vie Sub')) self.actionOpenViewedVideo.setText( _translate("Form", 'Open Viewed Video'))