def __alarm(self): if not self.go: return; self.timer.stop() player = QMediaPlayer(self); player.setMedia(QMediaContent(QUrl.fromLocalFile(self.music))); player.setVolume(100); player.play(); self.setEnabled(False) QMessageBox.critical(self, "ALERTA", "TIME TO DIE<br>" + self.ui.groupBox.title(), QMessageBox.Yes) self.setEnabled(True) player.stop() player.deleteLater()
class VideoWindow(QWidget): def __init__(self, vidPath): super().__init__() self.fullPath = vidPath self.startTime = 0 self.endTime = 0 self.init_ui() def init_ui(self): layout = QVBoxLayout() self.setLayout(layout) self.setWindowTitle(self.fullPath) self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.videoWidget = QVideoWidget() self.playButton = QPushButton() self.playButton.setEnabled(True) self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay)) self.playButton.setFixedWidth(100) self.playButton.setFixedHeight(50) self.playButton.clicked.connect(self.play) self.trimButton = QPushButton("Trim") self.trimButton.setFixedWidth(150) self.trimButton.setFixedHeight(50) self.trimButton.clicked.connect(self.trimVid) self.positionSlider = QSlider(QtCore.Qt.Horizontal) self.positionSlider.setRange(0, 0) self.positionSlider.sliderMoved.connect(self.setPosition) self.rangeSlider = qrangeslider.QRangeSlider() self.rangeSlider.setRange(0, 0) self.rangeSlider.endValueChanged.connect(self.adjustForEnd) self.rangeSlider.startValueChanged.connect(self.adjustForStart) self.rangeSlider.setFixedHeight(15) self.startTimeInput = QTimeEdit() self.endTimeInput = QTimeEdit() self.startTimeInput.setDisplayFormat('hh:mm:ss.zzz') self.endTimeInput.setDisplayFormat('hh:mm:ss.zzz') self.startTimeInput.timeChanged.connect(self.startInputChanged) self.endTimeInput.timeChanged.connect(self.endInputChanged) self.mediaPlayer.setMedia( QMediaContent(QtCore.QUrl.fromLocalFile(self.fullPath))) layout.addWidget(self.videoWidget) self.mediaPlayer.setVideoOutput(self.videoWidget) self.mediaPlayer.setNotifyInterval(10) self.mediaPlayer.stateChanged.connect(self.mediaStateChanged) self.mediaPlayer.positionChanged.connect(self.positionChanged) self.mediaPlayer.durationChanged.connect(self.durationChanged) controlLayout = QVBoxLayout() controlLayout.setContentsMargins(0, 0, 0, 0) controlLayout.addWidget(self.rangeSlider) controlLayout.addWidget(self.positionSlider) timeInputLayout = QHBoxLayout() timeInputLayout.addWidget(self.playButton) timeInputLayout.addWidget(self.startTimeInput) timeInputLayout.addWidget(self.endTimeInput) timeInputLayout.addWidget(self.trimButton) controlLayout.addLayout(timeInputLayout) layout.addLayout(controlLayout) self.mediaPlayer.play() self.resize(1024, 700) self.show() def closeEvent(self, event): self.mediaPlayer.stop() self.videoWidget.setParent(None) self.mediaPlayer.setParent(None) self.mediaPlayer.deleteLater() self.videoWidget.deleteLater() def trimVid(self): self.trimButton.setEnabled(False) outName = mytools.getAvailableName(self.fullPath, 'Trim') print(outName) trimStartTime = self.startTimeInput.time().toString('hh:mm:ss.zzz') trimEndTime = self.endTimeInput.time().toString('hh:mm:ss.zzz') try: ff = FFmpeg(inputs={self.fullPath: None}, outputs={ outName: [ '-ss', trimStartTime, '-to', trimEndTime, '-c:v', 'copy', '-c:a', 'copy', ] }) ff.run() except Exception as e: msg = QMessageBox() msg.setWindowTitle("Trim Failed") msg.setText(str(e)) msg.setIcon(QMessageBox.Critical) showMsg = msg.exec_() self.trimButton.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) if position > self.endTime: self.mediaPlayer.setPosition(self.startTime) def adjustForStart(self, startPos): self.startTime = startPos self.mediaPlayer.setPosition(startPos) self.startTimeInput.setTime(QtCore.QTime(0, 0).addMSecs(startPos)) self.endTimeInput.setMinimumTime(QtCore.QTime(0, 0).addMSecs(startPos)) def adjustForEnd(self, endPos): self.endTime = endPos if self.positionSlider.value() > endPos: self.mediaPlayer.setPosition(endPos) self.endTimeInput.setTime(QtCore.QTime(0, 0).addMSecs(endPos)) self.startTimeInput.setMaximumTime(QtCore.QTime(0, 0).addMSecs(endPos)) def startInputChanged(self, inputTime): self.rangeSlider.setStart(QtCore.QTime(0, 0, 0, 0).msecsTo(inputTime)) def endInputChanged(self, inputTime): self.rangeSlider.setEnd(QtCore.QTime(0, 0, 0, 0).msecsTo(inputTime)) def durationChanged(self, duration): self.positionSlider.setRange(0, duration) self.rangeSlider.setMax(duration) self.rangeSlider.setEnd(duration) self.startTimeInput.setMinimumTime(QtCore.QTime(0, 0)) self.endTimeInput.setMinimumTime(QtCore.QTime(0, 0)) self.endTimeInput.setTime(QtCore.QTime(0, 0).addMSecs(duration)) self.startTimeInput.setMaximumTime( QtCore.QTime(0, 0).addMSecs(duration)) self.endTimeInput.setMaximumTime(QtCore.QTime(0, 0).addMSecs(duration)) def setPosition(self, position): self.mediaPlayer.setPosition(position)
class VideoPlayerWidget(QWidget): def __init__(self, QWidget_parent=None, Qt_WindowFlags_flags=0): QWidget.__init__(self, QWidget_parent) self.ui=Ui_VideoPlayerWidget() savecwd = os.getcwd() os.chdir('view/qt_ui') self.ui.setupUi(self) os.chdir(savecwd) self.duration=0 self.urls=list() self.default=-1 self.url=URL() self.saved_position=None self.media_player = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.media_player_widget = VideoWidget(self.ui.top_frame) self.ui.top_frame_layout.addWidget(self.media_player_widget) self.media_player.setVideoOutput(self.media_player_widget) self.media_player_widget.show() self.media_player.bufferStatusChanged.connect(lambda x:self.ui.buffer.setValue(x)) self.media_player.positionChanged.connect(self.positionChanged) self.media_player.durationChanged.connect(self.durationChanged) self.media_player.mediaStatusChanged.connect(self.media_status_changed) self.media_player.error.connect(self.handleError) # self.ui.buffer.hide() self.ui.bn_play.clicked.connect(self.media_player.play) self.ui.bn_pause.clicked.connect(self.media_player.pause) self.ui.bn_stop.clicked.connect(self.stop) self.ui.bn_mute.clicked.connect(self.media_player.setMuted) self.ui.progress.sliderMoved.connect(self.media_player.setPosition) self.ui.volume.valueChanged.connect(self.media_player.setVolume) def set_url_list(self, list_of_dict:list, default:int): self.urls=list_of_dict self.default=default self.set_url(self.urls[self.default]['url']) menu = QMenu(self) for item in self.urls: menu_action = QAction(item['text'], self, triggered=get_menu_handler(self.re_open,item['url'])) menu.addAction(menu_action) self.ui.bn_quality.setMenu(menu) def re_open(self, url:URL): self.saved_position=self.media_player.position() self.set_url(url) self.media_player.play() def set_url(self, url:URL): self.url=url request = QNetworkRequest(QUrl(url.get())) request.setHeader(QNetworkRequest.UserAgentHeader,url.user_agent) if url.referer: request.setRawHeader('Referer',url.referer.get()) # todo: сделать добавление cookie и подготовку proxу # print(request.rawHeaderList()) # print(request.rawHeader('User-Agent')) # print(request.rawHeader('Referer')) self.media_player.setMedia(QMediaContent(request)) # print(self.media_player.media().canonicalRequest()) def media_status_changed(self, media_status): if media_status == QMediaPlayer.BufferedMedia: if self.saved_position: self.media_player.setPosition(self.saved_position) self.saved_position = None def positionChanged(self, position): def time_format(ms): dur = ms // 1000 hours=dur // 3600 minutes = dur // 60 - hours*60 secundes = dur - minutes * 60- hours*3600 if hours==0: return '%2d:%02d' % (minutes, secundes) else: return '%d:%02d:%02d' % (hours, minutes, secundes) self.ui.progress.setValue(position) self.ui.lb_time.setText(time_format(position) + ' / ' + time_format(self.duration)) def durationChanged(self, duration): self.ui.progress.setRange(0, duration) self.duration = duration def little_forward(self, second:int): current_position=self.media_player.position() new_position=current_position + second*1000 if new_position < self.duration: self.media_player.setPosition(new_position) def play(self): self.media_player.play() def stop(self): self.media_player.stop() def pause(self): self.media_player.pause() def set_volume(self, volume:int): self.ui.volume.setValue(volume) self.media_player.setVolume(volume) def get_volume(self)->int: return self.ui.volume.value() def mute(self, on:bool): self.media_player.setMuted(on) self.ui.bn_mute.setChecked(on) def is_muted(self): return self.ui.bn_mute.isChecked() def set_error_handler(self, on_error=lambda error_text:None): self.on_error=on_error def handleError(self): # print(self.media_player.error()) print("Error in " + self.url.get() + ': ' + self.media_player.errorString()) self.on_error("Error in " + self.url.link() + ': ' + self.media_player.errorString()) # self.error_handler('Player error: ' + self.media_player.errorString()) def destroy(self, bool_destroyWindow=True, bool_destroySubWindows=True): self.media_player.deleteLater() super().destroy(bool_destroyWindow, bool_destroySubWindows)
class MainLogic(QWidget,Ui_Form,ParseData): def __init__(self): super().__init__() self.setWindowFlags(QtCore.Qt.FramelessWindowHint) self.setAttribute(QtCore.Qt.WA_TranslucentBackground) # 设置窗口背景透明 self.setWindowIcon(QIcon("source/logo1.png")) self.setupUi(self) self.widget_style() self.setCursor(Qt.ArrowCursor) def setVideo(self,url): self.player = QMediaPlayer() self.player.positionChanged.connect(self.playSlide) #进度条 self.play_sld.sliderMoved.connect(self.changeSlide) #进度条 self.video_widget = QVideoWidget(self.video_box) self.video_widget.setGeometry(0,0,100,100) self.video_widget.setAspectRatioMode(1) self.video_widget.show() self.verticalLayout_4.addWidget(self.video_widget) self.player.setMedia(QMediaContent(QUrl(url))) self.player.setVolume(50) #设置声音大小 self.player.setVideoOutput(self.video_widget) self.player.pause() def parse_video(self): try: self.parse_url(self.parse_le.text()) self.get_data() self.setVideo(self.play_addr) self.insertData() self.clear_btn.setEnabled(True) self.play_btn.setEnabled(True) self.download_btn.setEnabled(True) self.parse_btn.setEnabled(False) except: QMessageBox.critical(self, "解析失败", "请检查当前网络链接\n或者检查分享链接是否输入正确") def widget_style(self): self.min_btn = QPushButton(qtawesome.icon('fa.window-minimize', color='#ddd'), "",self.widget_3) self.min_btn.setMaximumSize(QtCore.QSize(50, 16777215)) self.min_btn.setStyleSheet("margin: 12px;padding: 2px 0;background:#b99910;border-radius:5px;") self.min_btn.setText("") self.min_btn.setAutoRepeatDelay(300) self.min_btn.setObjectName("min_btn") self.horizontalLayout.addWidget(self.min_btn) self.close_btn = QPushButton(qtawesome.icon('fa.window-close', color='#ddd'),'',self.widget_3) self.close_btn.setMaximumSize(QtCore.QSize(50, 16777215)) self.close_btn.setStyleSheet("margin: 12px;padding: 2px 0;background:#bf3b3b;border-radius:5px;") self.close_btn.setText("") self.close_btn.setObjectName("close_btn") self.horizontalLayout.addWidget(self.close_btn) self.min_btn.clicked.connect(self.showMinimized) self.close_btn.clicked.connect(self.close) self.parse_btn_2.setIcon(QIcon('source/parse.ico')) self.introduce_label.setAlignment(Qt.AlignTop) self.desc_label.setAlignment(Qt.AlignTop) def clear_data(self): self.clear_btn.setEnabled(False) self.play_btn.setEnabled(False) self.download_btn.setEnabled(False) self.parse_btn.setEnabled(True) self.player.deleteLater() self.video_widget.deleteLater() self.avatar_label.clear() self.author_name_label.clear() self.douyin_id_label.clear() self.introduce_label.clear() self.desc_label.clear() self.create_time_label.clear() self.video_size_label.clear() self.play_btn.setText('播放') self.play_sld.setValue(0) self.video_time.setText("00:00/00:00") def insertData(self): avatar = requests.get(self.author_avatar_addr,headers = self.headers).content img = QPixmap() img.loadFromData(avatar) self.avatar_label.setPixmap(img) self.avatar_label.setScaledContents(True) self.response = requests.get(self.play_addr, headers=self.headers) self.video_size = str(format(int(self.response.headers['Content-Length']) / 1048576, ".2f") + " Mb") self.author_name_label.setText(self.author_nickname) self.douyin_id_label.setText(self.author_unique_id) self.introduce_label.setText(self.author_signature) self.desc_label.setText(self.douyin_desc) self.video_size_label.setText(self.video_size) self.create_time_label.setText(str(self.douyin_create_time)) def playSlide(self,position): self.vidoeLength = self.player.duration() + 0.01 videoLength = divmod(round(position / 1000), 60) self.video_time.setText(f'{str("%02d:%02d" % (videoLength[0],videoLength[1]))}/{self.video_duration}') self.play_sld.setValue(round((position/self.vidoeLength)*100)) if self.vidoeLength > 0.01 and round(position) == round(self.vidoeLength): #判断是否播放结束 self.play_btn.setText('播放') self.play_sld.setValue(0) def changeSlide(self): self.play_position = round(self.play_sld.value()/100 * self.v_length) self.player.setPosition(self.play_position) def play(self): if self.play_btn.text() == '播放' and self.vidoeLength > 0.01: self.play_btn.setText('暂停') self.player.play() else: self.play_btn.setText('播放') self.player.pause() def download(self): fw = open(self.desc_label.text() + '.mp4', "wb") chunk_size = 1048576 r = requests.get(self.play_addr, headers=self.headers, stream=True) filesize = self.response.headers['Content-Length'] if filesize is None: fw.write(r.content) else: dl = 0 total_length = int(filesize) t1 = time.time() for data in r.iter_content(chunk_size): dl += len(data) show = dl / total_length fw.write(data) t2 = time.time() t = t2 - t1 speed = dl / 1024 / 1024 / t self.progressBar.setValue(show * 100) self.download_speed_label.setText(f'{str(speed)[0:4]}M/s') def mouseMoveEvent(self, e: QMouseEvent): # 重写移动事件 try: self._endPos = e.pos() - self._startPos self.move(self.pos() + self._endPos) except: pass def mousePressEvent(self, e: QMouseEvent): if e.button() == QtCore.Qt.LeftButton: self._isTracking = True self._startPos = QtCore.QPoint(e.x(), e.y()) def mouseReleaseEvent(self, e: QMouseEvent): if e.button() == QtCore.Qt.LeftButton: self._isTracking = False self._startPos = None self._endPos = None