Пример #1
0
class VideoPlayer(QWidget):

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

        self.setAttribute(Qt.WA_NoSystemBackground, True)
        self.setAcceptDrops(True)
        
        self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.StreamPlayback)
        self.mediaPlayer.setVolume(80)
        
        self.videoWidget = QVideoWidget(self)
        self.videoWidget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.videoWidget.setMinimumSize(QSize(640, 360))
        
        self.lbl = QLineEdit('00:00:00')
        self.lbl.setReadOnly(True)
        self.lbl.setFixedWidth(70)
        self.lbl.setUpdatesEnabled(True)
        self.lbl.setStyleSheet(stylesheet(self))

        self.elbl = QLineEdit('00:00:00')
        self.elbl.setReadOnly(True)
        self.elbl.setFixedWidth(70)
        self.elbl.setUpdatesEnabled(True)
        self.elbl.setStyleSheet(stylesheet(self))

        self.playButton = QPushButton()
        self.playButton.setEnabled(False)
        self.playButton.setFixedWidth(32)
        self.playButton.setStyleSheet("background-color: black")
        self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
        self.playButton.clicked.connect(self.play)

        self.positionSlider = QSlider(Qt.Horizontal, self)
        self.positionSlider.setStyleSheet(stylesheet(self))
        self.positionSlider.setRange(0, 100)
        self.positionSlider.sliderMoved.connect(self.setPosition)
        self.positionSlider.sliderMoved.connect(self.handleLabel)
        self.positionSlider.setSingleStep(2)
        self.positionSlider.setPageStep(20)
        self.positionSlider.setAttribute(Qt.WA_TranslucentBackground, True)

        self.clip = QApplication.clipboard()
        self.process = QProcess(self)
        self.process.readyRead.connect(self.dataReady)
        self.process.finished.connect(self.playFromURL)

        self.myurl = ""

        # channel list
        self.channelList = QListView(self)
        self.channelList.setMinimumSize(QSize(150, 0))
        self.channelList.setMaximumSize(QSize(150, 4000))
        self.channelList.setFrameShape(QFrame.Box)
        self.channelList.setObjectName("channelList")
        self.channelList.setStyleSheet("background-color: black; color: #585858;")
        self.channelList.setFocus()
        # for adding items to list must create a model
        self.model = QStandardItemModel()
        self.channelList.setModel(self.model)

        self.controlLayout = QHBoxLayout()
        self.controlLayout.setContentsMargins(5, 0, 5, 0)
        self.controlLayout.addWidget(self.playButton)
        self.controlLayout.addWidget(self.lbl)
        self.controlLayout.addWidget(self.positionSlider)
        self.controlLayout.addWidget(self.elbl)

        self.mainLayout = QHBoxLayout()

        # contains video and cotrol widgets to the left side
        self.layout = QVBoxLayout()
        self.layout.setContentsMargins(0, 0, 0, 0)
        self.layout.addWidget(self.videoWidget)
        self.layout.addLayout(self.controlLayout)
        
        # adds channels list to the right
        self.mainLayout.addLayout(self.layout)
        self.mainLayout.addWidget(self.channelList)

        self.setLayout(self.mainLayout)

        self.myinfo = "©2020\nTIVOpy v1.0"

        self.widescreen = True

        #### shortcuts ####
        self.shortcut = QShortcut(QKeySequence("q"), self)
        self.shortcut.activated.connect(self.handleQuit)
        self.shortcut = QShortcut(QKeySequence("u"), self)
        self.shortcut.activated.connect(self.playFromURL)
        self.shortcut = QShortcut(QKeySequence(Qt.Key_Space), self)
        self.shortcut.activated.connect(self.play)
        self.shortcut = QShortcut(QKeySequence(Qt.Key_F), self)
        self.shortcut.activated.connect(self.handleFullscreen)
        self.shortcut = QShortcut(QKeySequence(Qt.Key_Escape), self)
        self.shortcut.activated.connect(self.exitFullscreen)
        self.shortcut.activated.connect(self.handleFullscreen)
        self.shortcut = QShortcut(QKeySequence("i"), self)
        self.shortcut.activated.connect(self.handleInfo)
        self.shortcut = QShortcut(QKeySequence("s"), self)
        self.shortcut.activated.connect(self.toggleSlider)
        self.shortcut = QShortcut(QKeySequence(Qt.Key_Right), self)
        self.shortcut.activated.connect(self.forwardSlider)
        self.shortcut = QShortcut(QKeySequence(Qt.Key_Left), self)
        self.shortcut.activated.connect(self.backSlider)

        self.mediaPlayer.setVideoOutput(self.videoWidget)
        self.mediaPlayer.stateChanged.connect(self.mediaStateChanged)
        self.mediaPlayer.positionChanged.connect(self.positionChanged)
        self.mediaPlayer.positionChanged.connect(self.handleLabel)
        self.mediaPlayer.durationChanged.connect(self.durationChanged)
        self.mediaPlayer.error.connect(self.handleError)

        self.populateChannelList()
        self.selectChannel()
        self.initialPlay()

    def playFromURL(self):
        self.mediaPlayer.pause()
        self.myurl = self.clip.text()
        self.mediaPlayer.setMedia(QMediaContent(QUrl(self.myurl)))
        self.playButton.setEnabled(True)
        self.mediaPlayer.play()
        self.hideSlider()
        print(self.myurl)

    def dataReady(self):
        self.myurl = str(self.process.readAll(), encoding='utf8').rstrip()  ###
        self.myurl = self.myurl.partition("\n")[0]
        print(self.myurl)
        self.clip.setText(self.myurl)
        self.playFromURL()

    def play(self):
        if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
            self.mediaPlayer.pause()
        else:
            self.mediaPlayer.play()

    def mediaStateChanged(self, state):
        if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
            self.playButton.setIcon(
                self.style().standardIcon(QStyle.SP_MediaPause))
        else:
            self.playButton.setIcon(
                self.style().standardIcon(QStyle.SP_MediaPlay))

    def positionChanged(self, position):
        self.positionSlider.setValue(position)

    def durationChanged(self, duration):
        self.positionSlider.setRange(0, duration)
        mtime = QTime(0, 0, 0, 0)
        mtime = mtime.addMSecs(self.mediaPlayer.duration())
        self.elbl.setText(mtime.toString())

    def setPosition(self, position):
        self.mediaPlayer.setPosition(position)

    def handleError(self):
        self.playButton.setEnabled(False)
        print("Error: ", self.mediaPlayer.errorString())

    def handleQuit(self):
        self.mediaPlayer.stop()
        print("Goodbye ...")
        app.quit()

    def contextMenuRequested(self, point):
        menu = QMenu()
        actionURL = menu.addAction(QIcon.fromTheme("browser"), "URL from Clipboard (u)")
        menu.addSeparator()
        actionToggle = menu.addAction(QIcon.fromTheme("next"), "Show / Hide Channels (s)")
        actionFull = menu.addAction(QIcon.fromTheme("view-fullscreen"), "Fullscreen (f)")
        menu.addSeparator()
        actionInfo = menu.addAction(QIcon.fromTheme("help-about"), "About (i)")
        menu.addSeparator()
        actionQuit = menu.addAction(QIcon.fromTheme("application-exit"), "Exit (q)")

        actionQuit.triggered.connect(self.handleQuit)
        actionFull.triggered.connect(self.handleFullscreen)
        actionInfo.triggered.connect(self.handleInfo)
        actionToggle.triggered.connect(self.toggleSlider)
        actionURL.triggered.connect(self.playFromURL)
        menu.exec_(self.mapToGlobal(point))

    def wheelEvent(self, event):
        mscale = event.angleDelta().y() / 13
        self.mediaPlayer.setVolume(self.mediaPlayer.volume() + mscale)
        print("Volume: " + str(self.mediaPlayer.volume()))

    def mouseDoubleClickEvent(self, event):
        if event.buttons() == Qt.LeftButton:
            self.handleFullscreen()

    def handleFullscreen(self):
        if self.windowState() and Qt.WindowFullScreen:
            self.showNormal()
        else:
            self.showFullScreen()

    def exitFullscreen(self):
        self.showNormal()

    def handleInfo(self):
        QMessageBox.about(self, "About", self.myinfo)

    def toggleSlider(self):
        if self.positionSlider.isVisible():
            self.hideSlider()
        else:
            self.showSlider()

    def hideSlider(self):
        self.channelList.hide()
        self.playButton.hide()
        self.lbl.hide()
        self.positionSlider.hide()
        self.elbl.hide()

    def showSlider(self):
        self.channelList.show()
        self.playButton.show()
        self.lbl.show()
        self.positionSlider.show()
        self.elbl.show()
        self.channelList.setFocus()

    def forwardSlider(self):
        self.mediaPlayer.setPosition(self.mediaPlayer.position() + 1000 * 60)

    def backSlider(self):
        self.mediaPlayer.setPosition(self.mediaPlayer.position() - 1000 * 60)

    def volumeUp(self):
        self.mediaPlayer.setVolume(self.mediaPlayer.volume() + 10)
        print("Volume: " + str(self.mediaPlayer.volume()))

    def volumeDown(self):
        self.mediaPlayer.setVolume(self.mediaPlayer.volume() - 10)
        print("Volume: " + str(self.mediaPlayer.volume()))

    def dragEnterEvent(self, event):
        if event.mimeData().hasUrls():
            event.accept()
        elif event.mimeData().hasText():
            event.accept()
        else:
            event.ignore()

    def dropEvent(self, event):
        print("drop")
        if event.mimeData().hasUrls():
            url = event.mimeData().urls()[0].toString()
            print("url = ", url)
            self.mediaPlayer.stop()
            self.mediaPlayer.setMedia(QMediaContent(QUrl(url)))
            self.playButton.setEnabled(True)
            self.mediaPlayer.play()
        elif event.mimeData().hasText():
            mydrop = event.mimeData().text()
            print("generic url = ", mydrop)
            self.mediaPlayer.setMedia(QMediaContent(QUrl(mydrop)))
            self.playButton.setEnabled(True)
            self.mediaPlayer.play()
            self.hideSlider()

    def loadFilm(self, f):
        self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile(f)))
        self.playButton.setEnabled(True)
        self.mediaPlayer.play()

    def populateChannelList(self):
        # file must be in same directory as the script
        FILEPATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), "canaletv.txt")
        # lines from file with "channel name" -- "link"
        channelArray = []
        # split file by line and adding it to the array
        with open(FILEPATH) as f:
            for line in f:
                channelArray.append(line.rstrip())
        # dictionary with key = channel name and value = link
        self.channelDict = dict(ch.split(" -- ") for ch in channelArray)
        for channel in self.channelDict.keys():
            item = QStandardItem(channel)
            self.model.appendRow(item)

    def selectedItemBehavior(self, index):
    # gets the link for the selected channel and plays it
        itms = self.channelList.selectedIndexes()
        for it in itms:
            channel = it.data()
            link = self.channelDict[channel]
            self.mediaPlayer.setMedia(QMediaContent(QUrl(link)))
            self.play()

    def selectChannel(self):
    # selecting channel from sidebar calls selectedItemBehavior
        self.selModel = self.channelList.selectionModel()
        self.selModel.selectionChanged.connect(self.selectedItemBehavior)

    def initialPlay(self):
    # play somenting when app opens
        self.mediaPlayer.setMedia(QMediaContent(QUrl("https://vid.hls.protv.ro/proxhdn/proxhd_3_34/index.m3u8?1")))
        self.play()

    def handleLabel(self):
        self.lbl.clear()
        mtime = QTime(0, 0, 0, 0)
        self.time = mtime.addMSecs(self.mediaPlayer.position())
        self.lbl.setText(self.time.toString())
Пример #2
0
class AppWindow(QMainWindow):
    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)
        self.setGeometry(100, 100, 550, 400)
        self.setUpMenu()
        self.setUpLayout()
        self.checkBoxConnect.stateChanged.connect(self.connect_disconnect)
        self.addButton.clicked.connect(self.add_contact)
        self.deleteButton.clicked.connect(self.delete_contact)
        self.sendButton.clicked.connect(self.send_message)
        self.contactsList.clicked.connect(self.select_contact)
        # self.messageField.drop.connect(self.add_file_to_message)

        # model -controller - view
        self.contact_list_model = StandardItemModelContacts(self)
        self.messages_list_model = StandardItemModelMessages(self)
        self.model = ClientModel(self.contact_list_model,
                                 self.messages_list_model)
        self.contactsList.setModel(self.contact_list_model)
        self.messagesList.setModel(self.messages_list_model)
        self.controller = ClientController(self.model)

        # signal-slot
        self.controller.auth_recieved.connect(self.authentification_recieved)
        self.controller.gotPersonal.connect(self.new_personal_message)

        # not connected
        self.connected = False
        # nobody selected
        self.currently_selected = ''

    def setUpMenu(self):
        fileMenu = self.menuBar().addMenu('File')
        quitAct = QAction('Quit', self)
        quitAct.triggered.connect(self.doQuit)
        fileMenu.addAction(quitAct)
        sendMenu = self.menuBar().addMenu('Send')
        sendFile = QAction('Send File', self)
        sendFile.triggered.connect(self.doSendFile)
        sendMenu.addAction(sendFile)

    def setUpLayout(self):
        hBoxLayout = QHBoxLayout()
        mainFrame = QFrame()
        mainFrame.setLayout(hBoxLayout)

        self.contact = QLineEdit()
        self.contact.setFont(QFont('Calibri', 14))
        self.contact.setPlaceholderText('Add Contact Here')
        self.contact.setMinimumHeight(30)
        self.contact.setMaximumHeight(30)

        self.addButton = QPushButton('+')
        self.addButton.setMinimumHeight(30)
        self.addButton.setMaximumHeight(30)
        self.addButton.setMinimumWidth(30)
        self.addButton.setMaximumWidth(30)

        self.deleteButton = QPushButton('-')
        self.deleteButton.setMinimumHeight(30)
        self.deleteButton.setMaximumHeight(30)
        self.deleteButton.setMinimumWidth(30)
        self.deleteButton.setMaximumWidth(30)

        self.contactsList = QListView()
        self.contactsList.setFrameShape(QFrame.Box)

        spacer = QFrame()
        spacer.setMaximumWidth(5)

        self.nameLabel = QLabel('Username')
        self.nameLabel.setMinimumHeight(30)
        self.nameLabel.setMaximumHeight(30)
        self.nameLabel.setFont(QFont('Calibri', 14))
        self.checkBoxConnect = QCheckBox()
        self.checkBoxConnect.setText('Connect')
        self.checkBoxConnect.setChecked(False)
        self.checkBoxConnect.setMaximumHeight(30)
        self.checkBoxConnect.setMinimumHeight(30)
        self.checkBoxConnect.setMaximumWidth(70)
        self.checkBoxConnect.setMinimumWidth(70)

        self.messagesList = QListView()
        self.messagesList.setIconSize(QSize(30, 30))
        self.messagesList.setFrameShape(QFrame.Box)
        self.messageField = MessageField()
        self.messageField.setMinimumHeight(50)
        self.messageField.setMaximumHeight(50)
        self.sendButton = QPushButton()
        self.sendButton.setText('>>')
        self.sendButton.setMinimumHeight(50)
        self.sendButton.setMaximumHeight(50)
        self.sendButton.setMinimumWidth(50)
        self.sendButton.setMaximumWidth(50)

        contBox = QGridLayout()
        contBox.addWidget(self.contact, 0, 0)
        contBox.addWidget(self.addButton, 0, 1)
        contBox.addWidget(self.deleteButton, 0, 2)
        contBox.addWidget(self.contactsList, 1, 0, 2, 3)
        contBox.addWidget(spacer, 0, 3, 3, 1)
        contBox.addWidget(self.nameLabel, 0, 4)
        contBox.addWidget(self.checkBoxConnect, 0, 5, 1, 2)
        contBox.addWidget(self.messagesList, 1, 4, 1, 3)
        contBox.addWidget(self.messageField, 2, 4, 1, 2)
        contBox.addWidget(self.sendButton, 2, 6)
        contBox.setColumnStretch(0, 3)
        contBox.setColumnStretch(4, 6)
        groupBoxCont = QFrame()
        groupBoxCont.setLayout(contBox)

        self.setCentralWidget(groupBoxCont)

    def doQuit(self):
        self.close()

    def doSendFile(self):
        filename = QFileDialog.getOpenFileName(self, 'Open file', '/home')[0]
        self.messageField.file = filename
        self.messageField.appendPlainText(filename)

    def connect_disconnect(self):
        self.checkBoxConnect.setEnabled(False)
        if self.checkBoxConnect.isChecked():
            self.authentification()
        else:
            self.user_disconnect()
            self.checkBoxConnect.setEnabled(True)

    # Log in  dialog
    def authentification(self):
        #read config file
        d = conf.read_conf()
        #show Authorization dialog
        auth_dialog = AuthDialog(self.model,
                                 d['username'],
                                 d['hostname'],
                                 d['port'],
                                 parent=self)
        auth_dialog.accepted.connect(self.auth_dialog_accepted)
        auth_dialog.rejected.connect(self.auth_dialog_rejected)
        auth_dialog.show()

    def auth_dialog_accepted(self):
        self.checkBoxConnect.setEnabled(True)
        self.controller.run_client()

    def auth_dialog_rejected(self):
        self.checkBoxConnect.setChecked(False)
        self.checkBoxConnect.setEnabled(True)

    @pyqtSlot(bool)
    def authentification_recieved(self, ok):
        if ok:
            self.connected = True
            self.checkBoxConnect.setText('Connected')
            self.nameLabel.setText('{}:'.format(self.model.username))
            self.model.contactlist.clear()
            self.model.personal_messages = []
            self.model.server_messages = []
            self.model.sent_messages = []
            self.model.open_db()
            self.controller.ask_contact_list()
        else:
            self.checkBoxConnect.setChecked(False)

    def user_disconnect(self):
        if self.connected:
            conf.save_conf(username=self.model.username,
                           hostname=self.model.host,
                           port=str(self.model.port))
            self.model.clear_data()
            self.controller.user_disconnect()
            self.contact.setText('')
            self.nameLabel.setText('')
            self.checkBoxConnect.setText('Connect')
            self.connected = False
            self.currently_selected = ''

    @pyqtSlot(str)
    def get_contact_list(self):
        pass

    def add_contact(self):
        name = self.contact.text()
        if name != '':
            self.controller.add_contact(name)
            self.contact.setText('')

    def delete_contact(self):
        name = self.contact.text()
        if name != '':
            self.controller.delete_contact(name)
            self.contact.setText('')

    @pyqtSlot(QMimeData)
    def add_file_to_message(self, mime):
        self.messageField.setPlainText(mime.text())

    def send_message(self):
        sel_list = self.contactsList.selectionModel().selectedIndexes()
        if len(sel_list) > 0:
            contact = self.model.contactlist.contacts[sel_list[0].row()]
            if self.messageField.file != '':
                self.controller.send_file(contact.name, self.messageField.file)
                self.messageField.file = ''
            else:
                self.controller.personal_message(
                    contact.name, self.messageField.toPlainText())
            self.messageField.clear()
            self.model.update_messages_for_contact(contact.name)
        else:
            pass

    @pyqtSlot(QModelIndex)
    def select_contact(self, modelindex):
        item = self.contact_list_model.data(modelindex, role=Qt.DisplayRole)
        contact_name = self.model.contactlist.contacts_name[modelindex.row()]
        self.contact.setText(contact_name)
        self.show_messages_for_contact(contact_name)
        self.contactsList.setCurrentIndex(modelindex)
        self.currently_selected = contact_name

    @pyqtSlot(str)
    def new_personal_message(self, sender):
        self.model.new_message_increase(sender, True)
        # sel_list = self.listViewContacts.selectionModel().selectedIndexes()
        if sender == self.currently_selected:
            self.show_messages_for_contact(self.currently_selected)

    @pyqtSlot(str)
    def show_messages_for_contact(self, contact_name):
        self.model.update_messages_for_contact(contact_name)
        self.model.new_message_increase(contact_name, False)
        self.messagesList.scrollToBottom()