class SoundThread(QThread): def __init__(self, parent=None): super(SoundThread, self).__init__(parent) self.name = "" home = expanduser("~") self.filename = home + "/Curie.mp3" wikipedia.set_lang("es") self.player = QMediaPlayer(None, QMediaPlayer.StreamPlayback) media = QMediaContent(QUrl.fromLocalFile(self.filename)) self.player.setMedia(media) def setName(self, name): self.name = name @pyqtSlot() def run(self): print(self.name) try: text = wikipedia.summary("{}".format(self.name), sentences=2) except wikipedia.DisambiguationError as e: text = wikipedia.summary("{} químico".format(self.name), sentences=2) print(e.options) tts = gTTS(text=text, lang='es') print(text) tts.save(self.filename) print("finish") self.player.play() print("play") def stop(self): self.player.stop()
class janela_vencedor(QWidget): def __init__(self, equipe_vencedora): QWidget.__init__(self) layout = QGridLayout() self.setLayout(layout) self.setFixedSize(800, 400) titulo = QLabel("CAMPEAO DO VOLBSI 2019") titulo.setStyleSheet("color: yellow") titulo.setFont(QFont("Courier", 36)) titulo.setAlignment(Qt.AlignHCenter) layout.addWidget(titulo) campeao = QLabel(f'\ {equipe_vencedora} /') campeao.setStyleSheet("color: white") campeao.setFont(QFont("Decorative", 48)) campeao.setAlignment(Qt.AlignCenter) layout.addWidget(campeao) self.botao_sair = QPushButton("SAIR") self.botao_sair.setFont(QFont("Courier", 16)) self.botao_sair.clicked.connect(quit) layout.addWidget(self.botao_sair) self.music = '/home/Documentos/projetos/volbsi/music.mp3' self.player = QMediaPlayer() self.player.setMedia(QMediaContent(QUrl.fromLocalFile(self.music))) self.player.play() self.show()
def play_file(self, filename, max_time_ms=None): """ Starts playing the sound file 'filename' and waits until playing is finish. When max_time_ms is specified the sound will terminate after the given milliseconds. """ app = QApplication(['PlaySoundClass']) app.setApplicationName("Audio Output Test") player = QMediaPlayer() #connect(player, SIGNAL(positionChanged(qint64)), this, SLOT(positionChanged(qint64))); player.stateChanged.connect(self._playerStateChanged) player.error.connect(self._playerError) url = QUrl.fromLocalFile( os.path.abspath(filename) ) # we need abspath otherwise a relative file does not work player.setMedia(QMediaContent(url)) player.setVolume(self.volume) if max_time_ms: timer = QTimer() # http://eli.thegreenplace.net/2011/04/25/passing-extra-arguments-to-pyqt-slot timer.singleShot(max_time_ms, lambda: self._playerDoStop(player)) player.play() app.exec_()
class VideoPlayer(QWidget): def __init__(self, parent=None): super(VideoPlayer, self).__init__(parent) self.media_player = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.video_item = QGraphicsVideoItem() 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.scene.addItem(self.video_item) layout = QVBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self.graphics_view) self.media_player.setVideoOutput(self.video_item) def play(self, url): self.media_player.setMedia(QMediaContent(QUrl.fromLocalFile(url))) self.media_player.play()
class ExampleApp(QtWidgets.QMainWindow, untitled.Ui_MainWindow): def __init__(self): # Main Processor ui class... super().__init__() self.setupUi(self) self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.mediaPlayer.positionChanged.connect(self.position_changed) self.mediaPlayer.durationChanged.connect(self.duration_changed) self.mediaPlayer.stateChanged.connect(self.mediastate_changed) self.horizontalSlider.sliderMoved.connect(self.set_position) self.horizontalSlider_2.sliderMoved.connect(self.set_volume) self.mediaPlayer.setVideoOutput(self.widget) self.pushButton.clicked.connect(self.open_file) self.pushButton_2.clicked.connect(self.play_video) self.pushButton_2.setIcon(self.style().standardIcon( QStyle.SP_MediaPlay)) self.horizontalSlider.setSliderPosition(0) self.mediaPlayer.setVolume(50) def open_file(self): filename, _ = QFileDialog.getOpenFileName(self, "Open Video") if filename != '': self.mediaPlayer.setMedia( QMediaContent(QUrl.fromLocalFile(filename))) self.pushButton_2.setEnabled(True) def play_video(self): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.mediaPlayer.pause() else: self.mediaPlayer.play() def mediastate_changed(self, state): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.pushButton_2.setIcon(self.style().standardIcon( QStyle.SP_MediaPause)) else: self.pushButton_2.setIcon(self.style().standardIcon( QStyle.SP_MediaPlay)) def position_changed(self, position): self.horizontalSlider.setValue(position) def duration_changed(self, duration): self.horizontalSlider.setRange(0, duration) def set_position(self, position): self.mediaPlayer.setPosition(position) def set_volume(self, position): value = self.horizontalSlider_2.value() self.mediaPlayer.setVolume(value) self.statusBar.showMessage("Громкость " + str(value) + " %")
class coppin(QWidget): def __init__(self): QWidget.__init__(self) p = self.palette() p.setColor(QPalette.Window, Qt.black) self.setPalette(p) self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint) self.center() self.init_ui() self.play() def center(self): #for load ui at center of screen frameGm = self.frameGeometry() screen = PyQt5.QtWidgets.QApplication.desktop().screenNumber( PyQt5.QtWidgets.QApplication.desktop().cursor().pos()) centerPoint = PyQt5.QtWidgets.QApplication.desktop().screenGeometry( screen).center() frameGm.moveCenter(centerPoint) self.move(frameGm.topLeft()) def init_ui(self): #create media player object self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface) videowidget = QVideoWidget() self.mediaPlayer.setVideoOutput(videowidget) vboxLayout = QVBoxLayout() vboxLayout.addWidget(videowidget) def play(self): self.mediaPlayer.setMedia( QMediaContent( QUrl.fromLocalFile(os.path.join(os.getcwd(), "warning3.mp4")))) self.mediaPlayer.play()
class PlayerDialog(QDialog): def __init__(self, video, dimensions, parent=None): QDialog.__init__(self, parent=parent, flags=QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint | QtCore.Qt.WindowCloseButtonHint) uic.loadUi('resources/videoplay.ui', self) self.videoWidget = QVideoWidget() self.stageLayout.addWidget(self.videoWidget) self.stage.setMinimumSize(QtCore.QSize(dimensions[0], dimensions[1])) self.playbtn.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay)) self.seekslider.mousePressEvent = self.__direct_slider_click self.seekslider.sliderMoved.connect(self.set_position) self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.mediaPlayer.setVideoOutput(self.videoWidget) self.mediaPlayer.stateChanged.connect(self.__media_state_changed) self.mediaPlayer.positionChanged.connect(self.__position_changed) self.mediaPlayer.durationChanged.connect(self.__duration_changed) self.mediaPlayer.error.connect(self.handle_error) self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile(video))) def __media_state_changed(self, state): if state == QMediaPlayer.PlayingState: self.playbtn.setIcon(self.style().standardIcon( QStyle.SP_MediaPause)) else: self.playbtn.setIcon(self.style().standardIcon( QStyle.SP_MediaPlay)) if state == QMediaPlayer.StoppedState: self.play() def __direct_slider_click(self, event): if event.button() == QtCore.Qt.LeftButton: calc_value = self.seekslider.minimum() + ( (self.seekslider.maximum() - self.seekslider.minimum()) * event.x()) / self.seekslider.width() self.seekslider.setValue(calc_value) self.set_position(calc_value) event.accept() QSlider.mousePressEvent(self.seekslider, event) def __position_changed(self, position): self.seekslider.setValue(position) def __duration_changed(self, duration): self.seekslider.setRange(0, duration) self.play() def handle_error(self): logger.error(self.mediaPlayer.errorString()) def play(self): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.mediaPlayer.pause() else: self.mediaPlayer.play() def set_position(self, position): self.mediaPlayer.setPosition(position)
class Player(): def __init__(self): self.player = QMediaPlayer() self.state = PLAYER_STATE_STOP def setMedia(self, music): self.player.setMedia(music) def play(self): print(self.player.mediaStatus()) if self.state == PLAYER_STATE_PAUSE: self.state = PLAYER_STATE_PLAY self.player.play() elif self.state == PLAYER_STATE_STOP: if self.player.mediaStatus() == LOADED_MEDIA: self.state = PLAYER_STATE_PLAY self.state.play() def pause(self): if self.state == PLAYER_STATE_PLAY: self.state = PLAYER_STATE_PAUSE self.player.pause() def stop(self): self.player.state = PLAYER_STATE_STOP
class BrainTankWindow(QMainWindow): def __init__(self, parent=None): QWidget.__init__(self, parent) self.setWindowTitle("BrainTank... BOOM!") self.setFixedSize(1024, 768) self.world = World() self.world.game_over.connect(self.close) self.setCentralWidget(self.world) self.media_player = QMediaPlayer() self.media_player.stateChanged.connect(self.media_player_state_changed) self.play_soundtrack() def media_player_state_changed(self, state): if state == QMediaPlayer.StoppedState: self.play_soundtrack() def play_soundtrack(self): project_dir = os.path.dirname( os.path.abspath(inspect.getfile(inspect.currentframe()))) url = QUrl.fromLocalFile("%s/Sounds/xmasmyth.mp3" % project_dir) mp3 = QMediaContent(url) self.media_player.setMedia(mp3) self.media_player.setVolume(20) self.media_player.play()
class MainWindow(QMainWindow): BACKSPACE_KEY_ID = 16777216 ESC_KEY_ID = 16777219 def __init__(self): super().__init__() QSound("resources/music.mp3").play() random_music_provider = RandomMusicProvider() self.url = QUrl.fromLocalFile(random_music_provider.get_random_music()) self.content = QMediaContent(self.url) self.player = QMediaPlayer() self.player.setMedia(self.content) self.menu_widget = MenuWidget(self) self.player.play() self.setCentralWidget(self.menu_widget) self.setGeometry(0, 0, 800, 800) def keyPressEvent(self, a0: QKeyEvent) -> None: if a0.key() == self.BACKSPACE_KEY_ID and isinstance( self.centralWidget(), GameWidget): self.centralWidget().change_meta_menud_state() if isinstance(self.centralWidget(), EndGameWinWidget): if a0.key() == self.ESC_KEY_ID: self.centralWidget().remove_name_symbol() return txt = a0.text() if len(txt) == 1: self.centralWidget().add_name_symbol(txt)
class PlayThread(QThread): def __init__(self, datasetPath, wav, snr): QThread.__init__(self) self.datasetPath = datasetPath self.wav = wav self.snr = snr def __del__(self): self.wait() def play(self, path): url = QUrl.fromLocalFile(path) content = QMediaContent(url) self.player = QMediaPlayer() self.player.setMedia(content) self.player.play() def stop(self): self.player.stop() def run(self): if self.wav < 10: wav_base_path = self.datasetPath + 'sounds/0000' + str(self.wav) else: wav_base_path = self.datasetPath + 'sounds/000' + str(self.wav) path = wav_base_path + '_' + str(self.snr) + '.wav' self.play(path) QThread.exec(self)
def notifySoundPlay(self): media = QMediaPlayer(self) media.setMedia( QMediaContent( QUrl.fromLocalFile(os.join(mainPath, "media", "notify.mp3")))) media.setVolume(100) media.play()
class VideoWindow(QVideoWidget): def __init__(self, filename): super().__init__() if not path.exists(filename): print("\nFile '{}' doesn't exist!".format(filename)) quit() self.width = SCREEN_WIDTH self.filename = filename self.video = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.video.setVideoOutput(self) #setting the video output self.video.mediaStatusChanged.connect( self.end_of_video) #setting a signal of the video end self.video.setMedia(QMediaContent( QUrl.fromLocalFile(filename))) #openning the file self.video.play() self.video.pause() def start(self): info_message( QMessageBox.Information, 'Instruction', 'In this part of the experiment, you will need to watch a video from the beginning till the end.\n\nNote: If you want to exit the experiment before the end, click the "Exit the experiment" buttom at the bottom of the screen.' ) self.video.play() def exit_confirmation(self): #asking confirmation to stop the video self.video.pause() returnValue = exit_question_message() if returnValue == QMessageBox.Yes: info_message(QMessageBox.Information, 'Experiment termination', 'The experiment has been stopped by the user') quit() else: self.video.play() def end_of_video(self, status): #responding to the end signal if status == self.video.EndOfMedia: info_message(QMessageBox.Information, 'The end of the video', 'The video has finished') if self.filename == FILENAME1: a = self.ask_A() if a != '3': info_message( QMessageBox.Information, 'The end of the experiment', 'This is the end of the experiment.\nThank you for your participation.' ) quit() experiment.next_in_scenario() def ask_A(self): '''ask how many A''' while True: #Doesn't allow to close the window items = ('0', '1', '2', '3', '4', '5') item, okPressed = QInputDialog().getItem( self, 'Question', 'How many letters A have you seen?\nThe number of A:', items, 0, False) if okPressed and item: return item
class BaselineProtocol(Protocol): translator = Translator() def __init__(self, signals, name='Baseline', update_statistics_in_the_end=True, text='Relax', half_time_text=None, voiceover=False, **kwargs): kwargs['name'] = name kwargs['update_statistics_in_the_end'] = update_statistics_in_the_end super().__init__(signals, **kwargs) self.text = text self.widget_painter = BaselineProtocolWidgetPainter( text=text, show_reward=self.show_reward) self.half_time_text_change = half_time_text is not None self.half_time_text = half_time_text self.is_half_time = False self.beep = SingleBeep() # audio self.voiceover = voiceover self._audio_player = QMediaPlayer() if self.voiceover: tfile = NamedTemporaryFile( delete=False) # Temporary file that stores audio recording... audio_path = tfile.name atexit.register(lambda: os.remove(audio_path) ) # ...that will be removed at program exit. # Write voiceover by using google translate text-to-speech and google translate language detector tts = gTTS(self.text, lang=self.translator.detect(self.text).lang) tts.write_to_fp(tfile) tfile.close() self._audio_player.setMedia( QMediaContent(QUrl.fromLocalFile(audio_path))) self._audio_played = False def update_state(self, samples, reward, chunk_size=1, is_half_time=False): if self.voiceover and not self._audio_played: self._audio_player.play() self._audio_played = True if self.half_time_text_change: if is_half_time and not self.is_half_time: self.beep.try_to_play() self.is_half_time = True self.widget_painter.set_message(self.half_time_text) def close_protocol(self, **kwargs): self.is_half_time = False self.beep = SingleBeep() self.widget_painter.set_message('') super(BaselineProtocol, self).close_protocol(**kwargs) self.widget_painter.set_message(self.text)
class Player(QDialog): def __init__(self): super().__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) # self.show() self.ui.btn_play.clicked.connect(self.playvideo) #включить видео self.ui.btn_stop.clicked.connect(self.stopvideo) #остановить видео self.ui.btn_pause.clicked.connect(self.pausevideo) #пауза self.ui.btn_back.clicked.connect(self.hidewindow) #скрыть окно плеера self.ui.verticalSlider.valueChanged.connect(self.setvolume) #громкость # self.ui.horizontalSlider.valueChanged.connect(self.settimevideo) #перемотка - починить функцию self.ui.listWidget.addItems(listdir("records")) #генерация списка файлов в папке records self.ui.listWidget.itemClicked.connect(self.playthis) #выбор видео self.player = QMediaPlayer() self.player.positionChanged.connect(self.setvideoonslider)#автодвижение ползунка self.video = QVideoWidget(self.ui.label) self.video.resize(621, 451) self.video.move(0, 0) self.player.setVideoOutput(self.video) self.video.show() self.ui.label.customContextMenuRequested.connect(self.testfun) #ПРАВАЯ КНОПКА МЫШИ def testfun(self): print("Тест успешен") def playvideo(self): self.player.play() self.ui.horizontalSlider.setMaximum(self.player.duration()) self.ui.horizontalSlider.setPageStep(self.player.duration() / 10) def stopvideo(self): self.player.stop() def pausevideo(self): self.player.pause() def hidewindow(self): self.hide() def setvolume(self): self.player.setVolume(self.ui.verticalSlider.value()) def settimevideo(self): self.player.setPosition(self.ui.horizontalSlider.value()) def playthis(self): self.player.setMedia(QMediaContent(QUrl.fromLocalFile("records/" + str(self.ui.listWidget.currentItem().text())))) def setvideoonslider(self): self.ui.horizontalSlider.setValue(self.player.position()) self.ui.lbl_time.setText(str(int(self.player.position() / 1000)) + "/" + str(int(self.player.duration() / 1000))) def test(self): print("Тест пройден")
class 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 Mp3Player(QWidget): def __init__(self): # super(Mp3Player, self).__init__(self) QWidget.__init__(self) self.player = QMediaPlayer(self) mp3 = QtCore.QUrl.fromLocalFile( '/tmp/2b5c07d6d9d32958d77f76546c36f5a8.mp3') self.player.setMedia(QMediaContent(mp3)) self.player.play()
class MyWin(QMainWindow): def __init__(self, parent=None): QMainWindow.__init__(self, parent) self.ui = Ui_VideoPlayer() self.ui.setupUi(self) self.media_player = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.media_player_widget = QVideoWidget(self.ui.mid_frame) self.ui.mid_frame_layout.addWidget(self.media_player_widget) self.media_player.setVideoOutput(self.media_player_widget) self.media_player.error.connect(self.handleError) # fileName="E:/Dropbox/Hobby/PRG/PyWork/FGet/view/qt_ui/files/1.mp4" # self.media_player.setMedia(QMediaContent(QUrl.fromLocalFile(fileName))) # fileName="E:/exchange/DiskD/kl/1/road_to_abbi_big-1080.mp4.Epidemz.net_Triksa.com.mp4" # self.media_player.setMedia(QMediaContent(QUrl.fromLocalFile(fileName))) self.ui.bn_go.clicked.connect(self.go) self.media_player.bufferStatusChanged.connect(self.buf) self.media_player.mediaStatusChanged.connect(self.med) # url='http://tubedupe.com/get_file/1/693b07616d5019e3e266e772676e3048/56000/56102/56102.mp4' url = 'http://tubedupe.com/get_file/1/4b274e3f4027b13bf6d6ae5601dd7a09/50000/50768/50768.mp4' url = 'http://www.mypornovideo.net/video_file/2015/2/830/grudastaja_blondinka_ebetsja_s_kuchejj_muzhikov.flv' url = "http://im.50f9bc00.493dea4.cdn2b.movies.mxn.com/0/399/399060/NOWATERMARK_IPOD.mp4?s=1423689551&e=1423696751&ri=1227&rs=44&h=d0a58a04acc858983a202b5e8dea575a" self.media_player.setMedia(QMediaContent(QUrl(url))) self.media_player.play() self.media_player.setMuted(True) print(self.media_player.duration()) print('Done') def handleError(self): print('Error: ' + self.media_player.errorString()) def buf(self, percent): print(percent, '%') def med(self, media): print(media) def go(self): dur = self.media_player.duration() pos = self.media_player.position() print(dur // 1000, pos // 1000) print(self.media_player.bufferStatus()) # self.hide() self.media_player.stop()
class PacmanWindow(QMainWindow): def __init__(self): super().__init__() self.initUI() def give(self, signal): self.signal = signal def initUI(self): self.board = game_painter.GameActions(self) self.statusbar = self.statusBar() self.board.ScoreSignal[str].connect(self.statusbar.showMessage) self.init_width = self.width() self.init_height = self.height() self.setWindowTitle('Pacman') self.setAutoFillBackground(True) p = self.palette() self.setStyleSheet('background-color: #0FB321;border-style: outset;' 'font: bold 14px;min-width: 10em;padding: 6px;') self.setPalette(p) def run(self, user): self.board = game_painter.GameActions(self) self.statusbar = self.statusBar() self.board.ScoreSignal[str].connect(self.statusbar.showMessage) self.player = QMediaPlayer() curr = os.getcwd() sound = QtMultimedia.QMediaContent( QUrl.fromLocalFile( os.path.join(curr, "music", "pacman_beginning.wav"))) self.player.setMedia(sound) self.player.play() self.player.setVolume(60) self.show() board = self.board board.start(user) self.setCentralWidget(board) self.resize(board.curr_game.board.width * board.scale, (board.curr_game.board.height + 4) * board.scale) def resizeEvent(self, event): self.board.resizeEvent_(self.init_width, self.init_height, self.width(), self.height()) def keyPressEvent(self, e): self.board.keyPressEvent(e) def closeEvent(self, *args, **kwargs): self.signal.emit()
class CamConfig(QWidget,_camconfig.Mixin): def __init__(self): super(CamConfig, self).__init__() self.setWindowTitle("Configurações de Câmera") self.setWindowIcon(QIcon('./gui/res/icon_device.png')) self.ipcamservices = IpCamServices() self.UI() self.populateCameras() def UI(self): layout = QHBoxLayout() self.setLayout(layout) self.ipcam = QUrl('') self.mp = QMediaPlayer() self.vw = QVideoWidget() self.media = QMediaContent(QNetworkRequest(self.ipcam)) self.mp.setMedia(self.media) self.mp.setVideoOutput(self.vw) #self.mp.play() self.vw.setSizePolicy(QSizePolicy.Expanding,QSizePolicy.Expanding) vbox = QVBoxLayout() vbox.addWidget(self.vw) layout.addLayout(vbox) #self.vw.show() form = QFormLayout() self.lstCameras = QListWidget() layout.addLayout(form) self.edtIP = QLineEdit() self.btnConnect = QPushButton('Conectar') self.btnSelectVideo = QPushButton('Selecionar vídeo') self.btnSave = QPushButton('Salvar modificações') self.btnConnect.clicked.connect(self.btnConnect_onclick) self.btnSave.clicked.connect(self.btnSave_onclick) self.btnSelectVideo.clicked.connect(self.btnSelectVideo_onclick) form.addRow(self.lstCameras) layout = QHBoxLayout() layout.addWidget(self.edtIP) layout.addWidget(self.btnConnect) form.addRow(layout) layout = QHBoxLayout() layout.addWidget(self.btnSelectVideo) layout.addWidget(self.btnSave) form.addRow(layout) self.lstCameras.currentRowChanged.connect(self.lstCameras_changed)
class Sound_thread(QThread): def __init__(self, fname, volume): super().__init__(None) self.player = QMediaPlayer() self.player.setMedia(QMediaContent(QUrl(fname))) self.player.setVolume(volume) def run(self): self.player.play()
def setup_music_player(filename: str): if not SoundUnit.check_music_file(filename): return None player = QMediaPlayer() try: player.setMedia(QMediaContent(QUrl.fromLocalFile(filename))) except QMediaPlayer.Error as e: print(e, file=sys.stderr) return None return player
def read_word(self): word = self.btn_word.text().strip() if os.path.exists(self.voice_dir+word+'.mp3'): player = QMediaPlayer(self) media_content = QMediaContent(QUrl.fromLocalFile(self.voice_dir+word+'.mp3')) player.setMedia(media_content) player.setVolume(100) player.play() else: self.download_voice()
def play(fileName): player = QMediaPlayer() player.setMedia(QMediaContent(QUrl.fromLocalFile(fileName))) player.play() def deletePlayer(status): if status == QMediaPlayer.EndOfMedia: player.deleteLater() player.mediaStatusChanged.connect(deletePlayer)
class MediaPlayer(metaclass=Observable): class Error(Enum): none = QMediaPlayer.NoError unsupported_format = QMediaPlayer.FormatError access_denied = QMediaPlayer.AccessDeniedError closed = signal() playing = signal(Track) stopped = signal(Track) error_occurred = signal(Track) def __init__(self): self._media_library = create_media_library() self._playlist = [] self._player = QMediaPlayer() self._player.stateChanged.connect(self._state_changed) self._player.mediaStatusChanged.connect(self._media_status_changed) def play(self, track): self._playlist.append(track) self._player.setMedia(self._media_library.fetch(track.filename)) self._player.play() def stop(self): self._player.stop() def _media_status_changed(self, state): if state == QMediaPlayer.BufferedMedia: self._error = QMediaPlayer.NoError self.playing.emit(self._playlist[0]) elif state == QMediaPlayer.InvalidMedia: # On windows 8, we only get an InvalidMedia status in case of error, # so we need to keep track of the error that occurred self._error = QMediaPlayer.FormatError @property def error(self): return MediaPlayer.Error(self._player.error() or self._error) def _state_changed(self, state): if state == QMediaPlayer.StoppedState and self.error is not MediaPlayer.Error.none: self.error_occurred.emit(self._playlist.pop(0), self.error) elif state == QMediaPlayer.StoppedState: self.stopped.emit(self._playlist.pop(0)) def dispose(self): self._player.stop() # force the deletion of the player on windows because windows # doesn't release the handle and prevents further instanciations sip.delete(self._player) self._player = None self._media_library.dispose() self.closed.emit()
def __init__(self, streams): self.streams = streams self.starting_player_indices = set(range(len(self.streams))) super().__init__() self.setAttribute(Qt.WA_QuitOnClose) self.setWindowFlags(Qt.FramelessWindowHint) palette = QPalette() palette.setColor(QPalette.Background, Qt.white) self.setPalette(palette) self.layout = QStackedLayout() self.setLayout(self.layout) label = QLabel() label.setAlignment(Qt.AlignCenter) self.loading_gif = QMovie("loading.gif") label.setMovie(self.loading_gif) self.layout.insertWidget(0, label) self.streams_ready.connect(self.showStartingScreen) self.players = [] for stream in self.streams: player = QMediaPlayer() player.setMedia(QMediaContent(stream)) player.mediaStatusChanged.connect(self.changedMediaStatus) player.play() self.players.append(player) grid_layout = QGridLayout() grid_layout.setSpacing(0) grid_layout.setContentsMargins(0, 0, 0, 0) self.grid_widget = QWidget() self.grid_widget.setLayout(grid_layout) i = 0 self.grid_widgets = [] for row in range(2): for column in range(2): video_item = QGraphicsVideoItem() self.players[i].setVideoOutput(video_item) video_widget = NumberedVideoWidget(i, video_item) self.grid_widgets.append(video_widget) grid_layout.addWidget(video_widget, row, column) i += 1 self.layout.insertWidget(1, self.grid_widget) video_item = QGraphicsVideoItem() video_widget = NumberedVideoWidget(4, video_item) self.players[4].setVideoOutput(video_item) self.layout.insertWidget(2, video_widget) self.loading_gif.start()
def initUI(self): self.resize(1920, 1200) self.main_widget = QWidget() # 创建窗口主部件 self.main_widget.setObjectName("main_widget") self.main_layout = QGridLayout() # 创建主部件的网格布局 self.main_widget.setLayout(self.main_layout) # self.setCentralWidget(self.main_widget) self.main_widget.setStyleSheet(''' #main_widget{ border-image:url(./Ui_images/blackB.jpg); border-radius:30px } } ''') self.gif = QMovie("./Ui_images/2.gif") self.scorelabel = QLabel(self.main_widget) self.scorelabel.setGeometry(800, 700, 140, 70) self.scorelabel.setMovie(self.gif) self.gif.start() self.videoframe = QLabel(self.main_widget) self.videoframe.setGeometry(1000, 200, 800, 448) self.scoreframe = QLabel(self.main_widget) self.scoreframe.setGeometry(965, 712, 150, 50) self.scoreframe.setAlignment(Qt.AlignVCenter) self.th = Thread(self.video_csv) self.th.changePixmap.connect(self.setImage) self.th.score.connect(self.setText) #self.th.finished.connect(self.save_ranking) self.th.start() time.sleep(2) vw1 = QVideoWidget(self.main_widget) vw1.setGeometry(100, 200, 800, 448) player = QMediaPlayer(self.main_widget) player.setVideoOutput(vw1) player.setMedia(QMediaContent(QUrl("file:///" + self.video_path))) player.play() # self.setWindowOpacity(0.9) # 设置窗口透明度 # self.setAttribute(Qt.WA_TranslucentBackground) # 设置窗口背景透明 #self.setWindowFlag(Qt.FramelessWindowHint) # 隐藏边框 self.show()
class MediaPlayer(metaclass=Observable): class Error(Enum): none = QMediaPlayer.NoError unsupported_format = QMediaPlayer.FormatError access_denied = QMediaPlayer.AccessDeniedError closed = signal() playing = signal(Track) stopped = signal(Track) error_occurred = signal(Track) def __init__(self): self._media_library = create_media_library() self._playlist = [] self._player = QMediaPlayer() self._player.stateChanged.connect(self._state_changed) self._player.mediaStatusChanged.connect(self._media_status_changed) def play(self, track): self._playlist.append(track) self._player.setMedia(self._media_library.fetch(track.filename)) self._player.play() def stop(self): self._player.stop() def _media_status_changed(self, state): if state == QMediaPlayer.BufferedMedia: self._error = QMediaPlayer.NoError self.playing.emit(self._playlist[0]) elif state == QMediaPlayer.InvalidMedia: # On windows 8, we only get an InvalidMedia status in case of error, # so we need to keep track of the error that occurred self._error = QMediaPlayer.FormatError @property def error(self): return MediaPlayer.Error(self._player.error() or self._error) def _state_changed(self, state): if state == QMediaPlayer.StoppedState and self.error is not MediaPlayer.Error.none: self.error_occurred.emit(self._playlist.pop(0), self.error) elif state == QMediaPlayer.StoppedState: self.stopped.emit(self._playlist.pop(0)) def dispose(self): self._player.stop() # force the deletion of the player on windows because windows # doesn't release the handle and prevents further instanciations sip.delete(self._player) self._player = None self._media_library.dispose() self.closed.emit()
def play_clip_sound(volume=100): filename = "sounds/clipsound.wav" fullpath = QDir.current().absoluteFilePath(filename) url = QUrl.fromLocalFile(fullpath) content = QMediaContent(url) player = QMediaPlayer() player.setMedia(content) player.setVolume(volume) player.play() time.sleep(0.3)
class Player(QGraphicsVideoItem): def __init__(self, parent=None): super().__init__() self.parent = parent self.player = QMediaPlayer() self.player.setVideoOutput(self) def playerPlayOrOpen(self, arg=None): if type(arg) == list and len(arg) > 1: content = QMediaContent(QUrl.fromLocalFile(arg[1])) self.player.setMedia(content) self.play() def addVideo(self, video): content = QMediaContent(QUrl.fromLocalFile(video)) self.player.setMedia(content) self.play() def sliderChanged(self, pos): self.player.setPosition(pos) def mouseDoubleClickEvent(self, event): if not self.parent.isFullScreen(): self.parent.showFullScreen() else: self.parent.showNormal() def play(self): self.player.play() def stop(self): self.player.stop() def pause(self): self.player.pause() def setMuted(self, mute): self.player.setMuted(mute) def mutedState(self): if self.player.isMuted(): self.setMuted(False) else: self.setMuted(True) def isMuted(self): return self.player.isMuted() def setVolume(self, value): self.player.setVolume(value) def volume(self): return self.player.volume()
class Player(QGraphicsVideoItem): def __init__(self, parent=None): super().__init__() self.parent = parent self.player = QMediaPlayer() self.player.setVideoOutput(self) def playerPlayOrOpen(self, arg=None): if type(arg) == list and len(arg) > 1: content = QMediaContent(QUrl.fromLocalFile(arg[1])) self.player.setMedia(content) self.play() def addVideo(self, video): content = QMediaContent(QUrl.fromLocalFile(video)) self.player.setMedia(content) self.play() def sliderChanged(self, pos): self.player.setPosition(pos) def mouseDoubleClickEvent(self, event): if not self.parent.isFullScreen(): self.parent.showFullScreen() else: self.parent.showNormal() def play(self): self.player.play() def stop(self): self.player.stop() def pause(self): self.player.pause() def setMuted(self, mute): self.player.setMuted(mute) def mutedState(self): if self.player.isMuted(): self.setMuted(False) else: self.setMuted(True) def isMuted(self): return self.player.isMuted() def setVolume(self, value): self.player.setVolume(value) def volume(self): return self.player.volume()
class 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 Objeto(QObject): def __init__(self): super().__init__() url = QUrl() url = url.fromLocalFile("cancion_1.wav") print(url) content = QMediaContent(url) print(content) self.player = QMediaPlayer() self.player.setMedia(content) self.player.play() print(self.player.supportedAudioRoles())
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 Window(QWidget): """ The main window of the application. Houses a media player and related controls. """ def __init__(self): super().__init__() layout = QVBoxLayout() self.slider = QSlider(Qt.Horizontal) btnOpen = QPushButton("Open") btnPlay = QPushButton("Play") self.player = QMediaPlayer() tl = Timeline(None, None) tlscroll = QScrollArea() tlscroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) tlscroll.setWidget(tl) btnOpen.clicked.connect(self.open) btnPlay.clicked.connect(self.play) self.player.durationChanged.connect(self.durationChanged) self.player.positionChanged.connect(self.positionChanged) layout.addWidget(self.slider) layout.addWidget(btnOpen) layout.addWidget(btnPlay) layout.addWidget(tlscroll) self.setLayout(layout) def open(self): fileName = QFileDialog.getOpenFileName(self, "Open File")[0] fileInfo = QFileInfo(fileName) if fileInfo.exists(): url = QUrl.fromLocalFile(fileInfo.absoluteFilePath()) self.changeMedia(QMediaContent(url)) def play(self): self.player.play() def changeMedia(self, mediaContent): self.player.setMedia(mediaContent) def durationChanged(self, duration): self.slider.setRange(0, duration) def positionChanged(self, position): self.slider.setValue(position)
def main(): app = QApplication(sys.argv) # Create media player, read media URL from first command line argument player = QMediaPlayer() media = QMediaContent(QUrl(sys.argv[1])) player.setMedia(media) # Create and set video output widget video = QVideoWidget() player.setVideoOutput(video) video.show() player.play() sys.exit(app.exec_())
class Video(QDialog): def __init__(self, video, parent=None): super(Video, self).__init__(parent) self.ui = Ui_Video() self.ui.setupUi(self) self.video = video self.setWindowTitle("Video - %s" % video.title) self.ui.urlEdit.setText(video.url) self.ui.titleLabel.setText(video.title) self.ui.durationLabel.setText(unicode(video.duration)) self.ui.authorLabel.setText(unicode(video.author)) self.ui.dateLabel.setText(unicode(video.date)) if video.rating_max: self.ui.ratingLabel.setText('%s / %s' % (video.rating, video.rating_max)) else: self.ui.ratingLabel.setText('%s' % video.rating) self.mediaPlayer = QMediaPlayer() self.mediaPlayer.durationChanged.connect(self._setMax) self.mediaPlayer.seekableChanged.connect(self.ui.seekSlider.setEnabled) self.mediaPlayer.positionChanged.connect(self._slide) self.ui.seekSlider.valueChanged.connect(self.mediaPlayer.setPosition) mc = QMediaContent(QUrl(video.url)) self.mediaPlayer.setMedia(mc) self.ui.videoPlayer.setMediaObject(self.mediaPlayer) self.mediaPlayer.play() @Slot('qint64') def _slide(self, pos): blocking = self.ui.seekSlider.blockSignals(True) self.ui.seekSlider.setValue(pos) self.ui.seekSlider.blockSignals(blocking) @Slot('qint64') def _setMax(self, duration): self.ui.seekSlider.setMaximum(duration) def closeEvent(self, event): self.mediaPlayer.stop() event.accept() def hideEvent(self, event): self.mediaPlayer.stop() event.accept()
class AudioPlayBack(): def __init__(self): self.__audioPlayback = QMediaPlayer() self.__audioPlayback.setVolume(50) self.__audioPlayback.positionChanged.connect(self.onTick) pass def onTick(self, e=None): print(self.__audioPlayback.position(), self.__audioPlayback.state()) Event.dis(AudioPlaybackEvent.TICK, self.__audioPlayback.position()) pass def load(self, path): content = QMediaContent(QUrl(path)) self.__audioPlayback.setMedia(content) self.__audioPlayback.play() pass def seek(self, position): self.__audioPlayback.setPosition(position) pass def play(self): if self.__audioPlayback.state() == QMediaPlayer.PausedState: self.__audioPlayback.play() pass pass def pause(self): if self.__audioPlayback.state() == QMediaPlayer.PlayingState: self.__audioPlayback.pause() pass pass # 0~100 def setVolume(self, vol): self.__audioPlayback.setVolume(vol) pass
class Speaker(QObject): def __init__(self, parent=None): super(Speaker,self).__init__(parent) self.player = QMediaPlayer(self) try: self.backup = steel.available_engines()[0]() self.backup.set("rate", 150) except: self.backup = None print("Could not start a backup offline speaker.") @pyqtSlot(str, str) def speak(self, name, text, lang="pt-br"): fpath = "./speeches/" + name + ".mp3" if not os.path.isdir("./speeches"): os.mkdir("./speeches") if not os.path.isfile(fpath): print("Running TTS...") try: data = urlencode( [("tl", lang), ("q", text), ("ie", "UTF-8")] ) bin_data = data.encode("utf8") req = Request("http://translate.google.com/translate_tts", bin_data, {"User-Agent":"My agent !"}) fin = urlopen(req) mp3 = fin.read() fout = open(fpath, "wb") fout.write(mp3) fout.close() except Exception as exc: print("Error trying to get TTS file:", str(exc)) if self.backup != None: print("Proceeding to use backup speaker...") self.backup.speak(text) return self.player.stop() self.player.setMedia(QMediaContent(QUrl.fromLocalFile(QFileInfo(fpath).absoluteFilePath()))) self.player.play()
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 Player(QGraphicsVideoItem): isSubtitle = pyqtSignal(bool) subtitlePos = pyqtSignal(int) def __init__(self, parent=None): super().__init__() self.parent = parent self.player = QMediaPlayer() self.player.setVolume(int(settings().value("Player/volume") or 100)) self.player.setVideoOutput(self) self.timer = QTimer(self) self.timer.timeout.connect(self.timerPos) self.player.currentMediaChanged.connect(self.signalStart) self.player.currentMediaChanged.connect(self.parent.subtitleitem.subtitleControl) self.player.currentMediaChanged.connect(self.videoConfigure) """self.player.mediaStatusChanged.connect(self.metadata) def metadata(self, data): if data and self.player.isMetaDataAvailable(): print(self.player.metaData("VideoCodec"))""" def videoConfigure(self, media): video_name = os.path.basename(media.canonicalUrl().toLocalFile()) videos = settings().value("Player/video_names") or [] videos_time = settings().value("Player/videos_time") or [] try: self.player.setPosition(int(videos_time[videos.index(video_name)])) except ValueError: pass def timerStart(self): self.timer.start(200) def signalStart(self, content): srt = content.canonicalUrl().toLocalFile().split(".") srt.pop(-1) srt.append("srt") srt = ".".join(srt) if QFile.exists(srt): self.isSubtitle.emit(True) self.timer.start(100) else: self.isSubtitle.emit(False) self.timer.stop() def timerPos(self): self.subtitlePos.emit(self.player.position()) def playerPlayOrOpen(self, arg=None): if type(arg) == list and len(arg) > 1: content = QMediaContent(QUrl.fromLocalFile(arg[1])) self.player.setMedia(content) self.play() def addVideo(self, video): content = QMediaContent(QUrl.fromLocalFile(video)) self.player.setMedia(content) self.play() def addYoutubeVideo(self, video): dm = DownloadManager(self) content = QMediaContent(dm.addUrl(video)) self.player.setMedia(content) self.play() def sliderChanged(self, pos): self.player.setPosition(pos) def play(self): self.player.play() def stop(self): self.player.stop() def pause(self): self.player.pause() def setMuted(self, mute): self.player.setMuted(mute) def mutedState(self): if self.player.isMuted(): self.setMuted(False) else: self.setMuted(True) def isMuted(self): return self.player.isMuted() def setVolume(self, value): self.player.setVolume(value) def volume(self): return self.player.volume()
super().__init__() def mouseReleaseEvent(self, _): self.clicked.emit() app = QApplication(sys.argv) # create stacked layout w = QStackedWidget() # add buttons btn1 = QPushButton("PLAY") player = QMediaPlayer() media = QMediaContent(QUrl(sys.argv[1])) player.setMedia(media) # Create and set video output widget video = ClickableVideoWidget() player.setVideoOutput(video) # add to stacked layout print("Added widget", w.addWidget(btn1)) print("Added widget", w.addWidget(video)) def play_video(): w.setCurrentIndex(1) player.play() def pause_video(): player.pause()
class Signal(QObject): """Represents a parsable media file undergoing transcription. A typical use case would be retrieving waveform data. """ signalFileChanged = pyqtSignal() stored_fps = 60 """int: number of waveform frames per second to store in memory.""" def __init__(self, file_name=None): """Set up a Signal object with the given file (or none by default). Args: file_name (str): File path of the file to open. Only .wav files permitted. """ super().__init__() self.file_name = None self.waveform_data = None self.waveform_info = None self.media_player = QMediaPlayer() self.open(file_name) def open(self, file_name): """Open the file at the given path for reading. Args: file_name (str): File path of the file to open. Only .wav files permitted. Raises: FileNotFoundError: If the filename given cannot be opened. """ if file_name is not None: file_info = QFileInfo(file_name) if file_info.exists(): self.file_name = file_name # Update the waveform data wave_read = wave.open(file_name, 'r') self.waveform_info = wave_read.getparams() step = int(self.waveform_info.framerate / self.stored_fps) self.waveform_data = list(bytesToInts( data=wave_read.readframes(-1), channelWidth=self.waveform_info.sampwidth, numChannels=self.waveform_info.nchannels, signed=True, step=step)) # Update the media player url = QUrl.fromLocalFile(file_info.absoluteFilePath()) self.media_player.setMedia(QMediaContent(url)) # Send out appropriate event self.signalFileChanged.emit() wave_read.close() else: raise FileNotFoundError('No file exists at given file path') def close(self): """Close the currently open signal file.""" self.file_name = None self.waveform_data = None self.waveform_info = None def play(self): """Play the currently open signal file.""" self.media_player.play() def is_available(self): """Returns true if a media file is actively loaded.""" return self.file_name is not None
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 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 QGisMap(QtWidgets.QWidget, Ui_Form): def __init__(self,projectfile,MainWidget): QtWidgets.QMainWindow.__init__(self) if os.name == 'nt': ffmpeg = os.path.dirname(__file__)[0:-18]+'/Video_UAV_Tracker/FFMPEG/ffmpeg.exe' versione = 'ffmpeg.exe' else: ffmpeg = os.path.dirname(__file__)+'/FFMPEG/./ffmpeg' versione = 'ffmpeg' if os.path.exists(ffmpeg) == True: self.setupUi(self) self.setWindowFlags(Qt.WindowStaysOnTopHint) self.Main = MainWidget self.projectfile = projectfile with open(self.projectfile,'r') as File: for line in File: if line[0:19] == 'Video file location': self.videoFile = line.split('=')[-1][1:-1] elif line[0:23] == 'Video start at msecond:': self.fps = (1 / (float(line.split()[7]))) * 1000 self.StartMsecond = int(line.split()[4]) elif line[0:4] == 'DB =': DB = line.split('=')[-1][1:-1] if DB == 'None': self.DB = None else: self.DB = DB break self.pushButton_3.setCheckable(True) self.EnableMapTool = False self.ExtractTool = 0 self.dockWidget_4.hide() self.GPXList = [] self.positionMarker=PositionMarker(self.Main.iface.mapCanvas()) self.muteButton.setIcon( self.style().standardIcon(QStyle.SP_MediaVolume)) self.playButton.setIcon( self.style().standardIcon(QStyle.SP_MediaPause)) self.player = QMediaPlayer() self.player.setVideoOutput(self.video_frame) self.playButton.clicked.connect(self.PlayPause) self.muteButton.clicked.connect(self.MuteUnmute) self.toolButton_11.clicked.connect(self.SkipBackward) self.toolButton_12.clicked.connect(self.SkipForward) self.SkipBacktoolButton_8.clicked.connect(self.BackwardFrame) self.SkipFortoolButton_9.clicked.connect(self.ForwardFrame) self.toolButton_4.clicked.connect(self.ExtractToolbar) self.toolButton_5.clicked.connect(self.close) self.pushButtonCut_2.clicked.connect(self.ExtractCommand) self.pushButtonCutA_6.clicked.connect(self.ExtractFromA) self.pushButtonCutB_6.clicked.connect(self.ExtractToB) self.pushButton_5.clicked.connect(self.CancelVertex) self.progressBar.hide() self.Main.pushButton_2.hide() self.Main.pushButton_8.hide() self.Main.groupBox.show() self.Main.groupBox_4.hide() self.ExtractA = False self.ExtractB = False self.ExtractedDirectory = None self.pushButtonCut_2.setEnabled(False) self.toolButton_6.setEnabled(False) self.LoadGPXVideoFromPrj(self.projectfile) else: ret = QMessageBox.warning(self, "Warning", 'missing ffmpeg binaries, please download it from https://github.com/sagost/VideoUavTracker/blob/master/FFMPEG/'+versione+' and paste it in /.qgis3/python/plugins/Video_UAV_Tracker/FFMPEG/ ', QMessageBox.Ok) self.close() def LoadGPXVideoFromPrj(self,VideoGisPrj): self.Polyline = [] with open(VideoGisPrj,'r') as File: Counter = 0 for line in File: if Counter < 5: pass else: line = line.split() lat = float(line[0]) lon = float(line[1]) ele = float(line[2]) speed = float(line[3]) course = float(line[4]) time = line[5] Point = [lat,lon,ele,speed,course,time] qgsPoint = QgsPoint(lon,lat) self.Polyline.append(qgsPoint) self.GPXList.append(Point) Counter = Counter + 1 self.GpsLayer = QgsVectorLayer("LineString?crs=epsg:4326", self.videoFile.split('.')[-2].split('/')[-1], "memory") self.pr = self.GpsLayer.dataProvider() feat = QgsFeature() feat.setGeometry(QgsGeometry.fromPolyline(self.Polyline)) self.pr.addFeatures([feat]) self.GpsLayer.updateExtents() if self.DB != None: try: self.DBLayer = QgsVectorLayer(self.DB,self.DB.split('.')[-2].split('/')[-1],'ogr') QgsProject.instance().addMapLayers([self.DBLayer,self.GpsLayer]) self.AddPointMapTool = AddPointTool(self.Main.iface.mapCanvas(),self.DBLayer,self) self.toolButton_6.clicked.connect(self.AddPointTool) self.toolButton_6.setEnabled(True) except: ret = QMessageBox.warning(self, "Warning", str(self.DB)+' is not a valid shapefile.', QMessageBox.Ok) return else: QgsProject.instance().addMapLayers([self.GpsLayer]) self.duration = len(self.GPXList) self.ExtractToB = self.duration self.horizontalSlider.setSingleStep(1000) self.horizontalSlider.setMinimum(0) self.horizontalSlider.setMaximum(len(self.GPXList)*1000) url = QUrl.fromLocalFile(str(self.videoFile)) mc = QMediaContent(url) self.player.setMedia(mc) self.player.setPosition(self.StartMsecond) self.player.play() self.horizontalSlider.sliderMoved.connect(self.setPosition) self.player.stateChanged.connect(self.mediaStateChanged) self.player.positionChanged.connect(self.positionChanged) self.pushButton_3.clicked.connect(self.MapTool) self.skiptracktool = SkipTrackTool( self.Main.iface.mapCanvas(),self.GpsLayer , self) def AddPointTool(self): self.Main.iface.mapCanvas().setMapTool(self.AddPointMapTool) def MapTool(self): if self.EnableMapTool == False: self.Main.iface.mapCanvas().setMapTool(self.skiptracktool) self.pushButton_3.setChecked(True) self.EnableMapTool = True else: self.Main.iface.mapCanvas().unsetMapTool(self.skiptracktool) self.pushButton_3.setChecked(False) self.EnableMapTool = False def closeEvent(self, *args, **kwargs): try: self.player.stop() self.Main.iface.mapCanvas().scene().removeItem(self.positionMarker) self.CancelVertex() self.Main.pushButton_2.show() #self.Main.horizontalSpacer_2.show() self.Main.groupBox.hide() self.Main.pushButton_8.show() self.Main.groupBox_4.show() self.dockWidget_2.close() except: pass return QtWidgets.QWidget.closeEvent(self, *args, **kwargs) def mediaStateChanged(self, state): if self.player.state() == QMediaPlayer.PlayingState: self.playButton.setIcon( self.style().standardIcon(QStyle.SP_MediaPause)) else: self.playButton.setIcon( self.style().standardIcon(QStyle.SP_MediaPlay)) def setPosition(self, position): self.player.setPosition(position+self.StartMsecond) def secTotime(self,seconds): m, s = divmod(seconds, 60) h, m = divmod(m, 60) return "%d:%02d:%02d" % (h, m, s) def positionChanged(self, progress): if progress < self.StartMsecond: self.player.setPosition(self.StartMsecond) progress = self.StartMsecond AssociatedGps = round((progress - self.StartMsecond )/1000) self.DisplayPoint(AssociatedGps) totalTime = self.secTotime(self.duration) actualTime = self.secTotime((progress - self.StartMsecond )/1000) self.replayPosition_label.setText(actualTime + ' / '+totalTime) if not self.horizontalSlider.isSliderDown(): self.horizontalSlider.setValue(progress - self.StartMsecond ) def DisplayPoint(self,Point): if Point >= len(self.GPXList): Point = len(self.GPXList) - 1 gpx = self.GPXList[Point] lat = round(gpx[0],7) lon = round(gpx[1],7) ele = gpx[2] speed = gpx[3] course = gpx[4] time = gpx[5] Point = QgsPointXY() Point.set(lon, lat) canvas = self.Main.iface.mapCanvas() crsSrc = QgsCoordinateReferenceSystem(4326) # .gpx is in WGS 84 crsDest = QgsProject.instance().crs() xform = QgsCoordinateTransform(crsSrc, crsDest) self.positionMarker.setHasPosition(True) self.Point = xform.transform(Point) self.positionMarker.newCoords(self.Point) self.positionMarker.angle = float(course) extent = canvas.extent() boundaryExtent=QgsRectangle(extent) boundaryExtent.scale(0.7) if not boundaryExtent.contains(QgsRectangle(Point, self.Point)): extentCenter= self.Point newExtent=QgsRectangle( extentCenter.x()-extent.width()/2, extentCenter.y()-extent.height()/2, extentCenter.x()+extent.width()/2, extentCenter.y()+extent.height()/2 ) self.Main.iface.mapCanvas().setExtent(newExtent) self.Main.iface.mapCanvas().refresh() self.Main.label_14.setText('GPS Time: '+str(time)) self.Main.label_15.setText('Course: '+"%.2f" % (course)) self.Main.label_16.setText('Ele: '+"%.2f" %(ele)) self.Main.label_17.setText('Speed m/s: '+"%.2f" %(speed)) self.Main.label_19.setText('Lat : '+str(lat)) self.Main.label_18.setText('Lon : '+str(lon)) def MuteUnmute(self): if self.player.mediaStatus() == 6 : if self.player.isMuted() == 1: self.player.setMuted(0) self.muteButton.setIcon( self.style().standardIcon(QStyle.SP_MediaVolume)) elif self.player.isMuted() == 0: self.player.setMuted(1) self.muteButton.setIcon( self.style().standardIcon(QStyle.SP_MediaVolumeMuted)) def SkipForward(self): position = self.player.position() self.player.setPosition(position+1000) def SkipBackward(self): position = self.player.position() self.player.setPosition(position-1000) def ForwardFrame(self): position = self.player.position() self.player.setPosition(position+int(self.fps)) def BackwardFrame(self): position = self.player.position() self.player.setPosition(position-int(self.fps)) def PlayPause(self): if self.player.state() == QMediaPlayer.PlayingState: self.player.pause() else: self.player.play() def findNearestPointInRecording(self, x,y): ClickPt = QgsPoint(x,y) Low = ClickPt.distanceSquared(self.Polyline[0]) NearPoint = 0 Counter = 0 for Point in self.Polyline: dist = ClickPt.distanceSquared(Point) if dist < Low: Low = dist NearPoint = Counter Counter = Counter + 1 else: Counter = Counter + 1 self.setPosition(NearPoint*1000) def ExtractSingleFrameOnTime(self, pos, outputfile): if os.name == 'nt': ffmpeg = ('"'+os.path.dirname(__file__)[0:-18]+'/Video_UAV_Tracker/FFMPEG/ffmpeg.exe'+'"') os.popen(str(ffmpeg)+' -ss '+str(pos/1000)+' -i '+str('"' +self.videoFile+ '"')+ ' -t 1 '+str('"'+outputfile+'"')) else: ffmpeg = os.path.dirname(__file__)+'/FFMPEG/./ffmpeg' os.system(str(ffmpeg)+' -ss '+str(pos/1000)+' -i '+str(self.videoFile)+' -t 1 '+str(outputfile)) def AddPoint(self,x,y): self.Main.iface.mapCanvas().unsetMapTool(self.AddPointMapTool) Point = QgsPointXY(x,y) pos = self.player.position() if self.player.state() == QMediaPlayer.PlayingState: self.player.pause() a = self.DBLayer.name() last_desc = '///' LayerName =str(a) last_desc2 = LayerName + ' Point N ' directory = str(self.DB.split('.')[0])+'_Image/' if not os.path.exists(directory): os.makedirs(directory) fc = int(self.DBLayer.featureCount()) self.ExtractSingleFrameOnTime(pos,directory+LayerName+'_'+str(fc)+'_.jpg') fields = self.DBLayer.fields() attributes = [] lat,lon = Point.y(), Point.x() for field in fields: a = str(field.name()) b = str(field.typeName()) if a == 'id': fcnr = fc attributes.append(fcnr) elif a == 'Lon(WGS84)': attributes.append(str(lon)) elif a == 'Lat(WGS84)': attributes.append(str(lat)) elif a == 'Image link': attributes.append(str(directory+LayerName+'_'+str(fc)+'_.jpg')) else: if b == 'String': (a,ok) = QInputDialog.getText( self.Main.iface.mainWindow(), "Attributes", a + ' = String', QLineEdit.Normal) attributes.append(a) elif b == 'Real': (a,ok) = QInputDialog.getDouble( self.Main.iface.mainWindow(), "Attributes", a + ' = Real', decimals = 10) attributes.append(a) elif b == 'Integer64': (a,ok) = QInputDialog.getInt( self.Main.iface.mainWindow(), "Attributes", a + ' = Integer') attributes.append(a) feature = QgsFeature() feature.setGeometry(QgsGeometry.fromPoint(Point)) feature.setAttributes(attributes) self.DBLayer.startEditing() self.DBLayer.addFeature(feature) self.DBLayer.commitChanges() self.DBLayer.triggerRepaint() def ExtractCommand(self): if self.ExtractToB <= self.ExtractFromA: ret = QMessageBox.warning(self, "Warning", '"To B" point must be after "from A" point', QMessageBox.Ok) self.CancelVertex() else: if os.name == 'nt': ffmpeg = '"'+os.path.dirname(__file__)[0:-18]+'/Video_UAV_Tracker/FFMPEG/ffmpeg.exe'+'"' else: ffmpeg = os.path.dirname(__file__)+'/FFMPEG/./ffmpeg' Directory,_ = QFileDialog.getSaveFileName(caption= 'Save georeferenced images') if Directory: self.progressBar.show() self.progressBar.setValue(0) start = self.ExtractFromA if self.comboBox_6.currentText() == 'seconds': finish = self.ExtractToB - self.ExtractFromA fps = self.doubleSpinBox_2.value() if fps < 1.0: fps = 1.0 / fps elif fps > 1: fps = 1.0 / fps if os.name == 'nt': os.popen(str(ffmpeg+ ' -ss ' + str(start) + ' -i '+ str('"'+self.videoFile+'"')+ ' -t ' + str(finish) + ' -vf fps=' + str(fps) + ' ' + '"'+Directory + '_%d.png'+'"')) else: os.system(ffmpeg+' -ss '+ str(start) + ' -i '+ str(self.videoFile) + ' -t ' + str(finish) + ' -vf fps=' + str(fps) + ' ' + Directory + '_%d.png') else: txtGPSFile = open(Directory + 'UTM_Coordinates.txt', 'w') txtGPSFile.close() txtGPSFile = open(Directory+ 'UTM_Coordinates.txt', 'a') txtGPSFile.write('filename # East UTM # North UTM # Ele '+ '\n') finish = self.ExtractToB meters = self.doubleSpinBox_2.value() Timerange = range(start, finish + 1) RemainToUseMeterTotal = 0 if os.name == 'nt': os.popen(ffmpeg+' -ss '+ str(start) + ' -i '+ str('"'+self.videoFile+'"') + ' -frames:v 1 ' + '"'+Directory + '_sec_' + str(start)+'.00.png'+'"') else: os.system(ffmpeg+' -ss '+ str(start) + ' -i '+ str(self.videoFile) + ' -frames:v 1 ' + Directory + '_sec_' + str(start)+'.00.png') lonUTM, latUTM,quotainutile = self.transform_wgs84_to_utm(float(self.GPXList[start][1]) , float(self.GPXList[start][0])) ele = float(self.GPXList[start][2]) txtGPSFile.write(str(Directory.split('/')[-1]) + '_sec_' + str(start)+'.00.png,'+' '+ str(lonUTM) + ', '+ str(latUTM) + ', ' + str(ele) + '\n') for i in Timerange: progessBarValue = ((i-start) * 100) // len(Timerange) self.progressBar.setValue(int(progessBarValue)) latitude1,longitude1 = float(self.GPXList[i][0]) ,float(self.GPXList[i][1]) latitude2,longitude2 = float(self.GPXList[i+1][0]) ,float(self.GPXList[i+1][1]) ele1 = float(self.GPXList[i][2]) ele2 = float(self.GPXList[i+1][2]) Calculus = Geodesic.WGS84.Inverse(latitude1, longitude1, latitude2, longitude2) DistanceBetweenPoint = Calculus['s12'] Azimuth = Calculus['azi2'] SpeedMeterSecond = DistanceBetweenPoint #GPS refresh rate is actually 1, change parameter for different rates # Time = 1 if RemainToUseMeterTotal == 0: if DistanceBetweenPoint >= meters: decimalSecondToAdd = meters / DistanceBetweenPoint RemainToUseMeter = DistanceBetweenPoint - meters if os.name == 'nt': os.popen(ffmpeg+ ' -ss '+ str(i + decimalSecondToAdd) + ' -i '+ str('"'+self.videoFile+'"') + ' -frames:v 1 ' +'"'+ Directory + '_sec_' + str(i) + str(decimalSecondToAdd)[1:4] +'.png'+'"') else: os.system(ffmpeg+ ' -ss '+ str(i + decimalSecondToAdd) + ' -i '+ str(self.videoFile) + ' -frames:v 1 ' + Directory + '_sec_' + str(i) + str(decimalSecondToAdd)[1:4] +'.png') CalculusDirect = Geodesic.WGS84.Direct(latitude1, longitude1, Azimuth,decimalSecondToAdd* SpeedMeterSecond) X,Y,quotainutile = self.transform_wgs84_to_utm(CalculusDirect['lon2'],CalculusDirect['lat2'] ) Z = ele1 + decimalSecondToAdd*(ele2 - ele1) txtGPSFile.write(str(Directory.split('/')[-1]) + '_sec_' + str(i) + str(decimalSecondToAdd)[1:4]+'.png,' + ' ' + str(X) + ', ' + str(Y) + ', ' + str(Z) + '\n') while RemainToUseMeter > meters: decimalSecondToAddMore = meters / SpeedMeterSecond RemainToUseMeter = RemainToUseMeter - meters decimalSecondToAdd = decimalSecondToAdd + decimalSecondToAddMore if os.name == 'nt': os.popen(ffmpeg+ ' -ss '+ str(i + decimalSecondToAdd) + ' -i '+ str('"'+self.videoFile+'"') + ' -frames:v 1 ' +'"'+ Directory + '_sec_' + str(i) + str(decimalSecondToAdd)[1:4] +'.png'+'"') else: os.system(ffmpeg+ ' -ss '+ str(i + decimalSecondToAdd) + ' -i '+ str(self.videoFile) + ' -frames:v 1 ' + Directory + '_sec_' + str(i) + str(decimalSecondToAdd)[1:4] +'.png') CalculusDirect = Geodesic.WGS84.Direct(latitude1, longitude1, Azimuth,decimalSecondToAdd* SpeedMeterSecond) X,Y,quotainutile = self.transform_wgs84_to_utm(CalculusDirect['lon2'],CalculusDirect['lat2'] ) Z = ele1 + decimalSecondToAdd*(ele2 - ele1) txtGPSFile.write(str(Directory.split('/')[-1]) + '_sec_' + str(i) + str(decimalSecondToAdd)[1:4]+'.png,' + ' ' + str(X) + ', ' + str(Y) + ', ' + str(Z) + '\n') if RemainToUseMeter == meters: decimalSecondToAddMore = meters / SpeedMeterSecond RemainToUseMeter = RemainToUseMeter - meters decimalSecondToAdd = decimalSecondToAdd + decimalSecondToAddMore if os.name == 'nt': os.popen(ffmpeg+ ' -ss '+ str(i + decimalSecondToAdd) + ' -i '+ str('"'+self.videoFile+'"') + ' -frames:v 1 ' +'"'+ Directory + '_sec_' + str(i) + str(decimalSecondToAdd)[1:4] +'.png'+'"') else: os.system(ffmpeg+ ' -ss '+ str(i + decimalSecondToAdd) + ' -i '+ str(self.videoFile) + ' -frames:v 1 ' + Directory + '_sec_' + str(i) + str(decimalSecondToAdd)[1:4] +'.png') CalculusDirect = Geodesic.WGS84.Direct(latitude1, longitude1, Azimuth,decimalSecondToAdd* SpeedMeterSecond) X,Y,quotainutile = self.transform_wgs84_to_utm(CalculusDirect['lon2'],CalculusDirect['lat2'] ) Z = ele1 + decimalSecondToAdd*(ele2 - ele1) txtGPSFile.write(str(Directory.split('/')[-1]) + '_sec_' + str(i) + str(decimalSecondToAdd)[1:4]+'.png,' + ' ' +str(X) + ', ' + str(Y) + ', ' + str(Z) + '\n') RemainToUseMeterTotal = 0 elif RemainToUseMeter < meters: RemainToUseMeterTotal = RemainToUseMeter pass else: RemainToUseMeterTotal = meters - DistanceBetweenPoint elif RemainToUseMeterTotal > 0: if DistanceBetweenPoint >= (meters - RemainToUseMeterTotal) : decimalSecondToAdd = (meters - RemainToUseMeterTotal) / DistanceBetweenPoint RemainToUseMeter = DistanceBetweenPoint - (meters - RemainToUseMeterTotal) if os.name == 'nt': os.popen(ffmpeg+ ' -ss '+ str(i + decimalSecondToAdd) + ' -i '+ str('"'+self.videoFile+'"') + ' -frames:v 1 ' +'"'+ Directory + '_sec_' + str(i) + str(decimalSecondToAdd)[1:4] +'.png'+'"') else: os.system(ffmpeg+ ' -ss '+ str(i + decimalSecondToAdd) + ' -i '+ str(self.videoFile) + ' -frames:v 1 ' + Directory + '_sec_' + str(i) + str(decimalSecondToAdd)[1:4] +'.png') CalculusDirect = Geodesic.WGS84.Direct(latitude1, longitude1, Azimuth,decimalSecondToAdd* SpeedMeterSecond) X,Y,quotainutile = self.transform_wgs84_to_utm(CalculusDirect['lon2'],CalculusDirect['lat2'] ) Z = ele1 + decimalSecondToAdd*(ele2 - ele1) txtGPSFile.write(str(Directory.split('/')[-1]) + '_sec_' + str(i) + str(decimalSecondToAdd)[1:4]+'.png,' + ' ' + str(X) + ', ' + str(Y) + ', ' + str(Z) + '\n') while RemainToUseMeter > meters: decimalSecondToAddMore = meters / SpeedMeterSecond RemainToUseMeter = RemainToUseMeter - meters decimalSecondToAdd = decimalSecondToAdd + decimalSecondToAddMore if os.name == 'nt': os.popen(ffmpeg+ ' -ss '+ str(i + decimalSecondToAdd) + ' -i '+ str('"'+self.videoFile+'"') + ' -frames:v 1 ' +'"'+ Directory + '_sec_' + str(i) + str(decimalSecondToAdd)[1:4] +'.png'+'"') else: os.system(ffmpeg+ ' -ss '+ str(i + decimalSecondToAdd) + ' -i '+ str(self.videoFile) + ' -frames:v 1 ' + Directory + '_sec_' + str(i) + str(decimalSecondToAdd)[1:4] +'.png') CalculusDirect = Geodesic.WGS84.Direct(latitude1, longitude1, Azimuth,decimalSecondToAdd* SpeedMeterSecond) X,Y,quotainutile = self.transform_wgs84_to_utm(CalculusDirect['lon2'],CalculusDirect['lat2'] ) Z = ele1 + decimalSecondToAdd*(ele2 - ele1) txtGPSFile.write(str(Directory.split('/')[-1]) + '_sec_' + str(i) + str(decimalSecondToAdd)[1:4]+'.png,' + ' ' + str(X) + ', ' + str(Y) + ', ' + str(Z) + '\n') if RemainToUseMeter == meters: decimalSecondToAddMore = meters / SpeedMeterSecond RemainToUseMeter = RemainToUseMeter - meters decimalSecondToAdd = decimalSecondToAdd + decimalSecondToAddMore if os.name == 'nt': os.popen(ffmpeg+ ' -ss '+ str(i + decimalSecondToAdd) + ' -i '+ str('"'+self.videoFile+'"') + ' -frames:v 1 ' +'"'+ Directory + '_sec_' + str(i) + str(decimalSecondToAdd)[1:4] +'.png'+'"') else: os.system(ffmpeg+ ' -ss '+ str(i + decimalSecondToAdd) + ' -i '+ str(self.videoFile) + ' -frames:v 1 ' + Directory + '_sec_' + str(i) + str(decimalSecondToAdd)[1:4] +'.png') CalculusDirect = Geodesic.WGS84.Direct(latitude1, longitude1, Azimuth,decimalSecondToAdd* SpeedMeterSecond) X,Y,quotainutile = self.transform_wgs84_to_utm(CalculusDirect['lon2'],CalculusDirect['lat2'] ) Z = ele1 + decimalSecondToAdd*(ele2 - ele1) txtGPSFile.write(str(Directory.split('/')[-1]) + '_sec_' + str(i) + str(decimalSecondToAdd)[1:4]+'.png,' + ' ' + str(X) + ', ' + str(Y) + ', ' + str(Z) + '\n') RemainToUseMeterTotal = 0 elif RemainToUseMeter < meters: RemainToUseMeterTotal = RemainToUseMeter else: RemainToUseMeterTotal = (meters - DistanceBetweenPoint) + RemainToUseMeterTotal txtGPSFile.close() self.progressBar.hide() def ExtractFromA(self): if self.ExtractA == True: self.Main.iface.mapCanvas().scene().removeItem(self.ExtractAVertex) self.ExtractA = False self.ExtractFromA = round((self.player.position()- self.StartMsecond )/1000) canvas = self.Main.iface.mapCanvas() crsSrc = QgsCoordinateReferenceSystem(4326) # .gpx is in WGS 84 crsDest = QgsProject.instance().crs() xform = QgsCoordinateTransform(crsSrc, crsDest) latitude,longitude = self.Polyline[self.ExtractFromA].y(), self.Polyline[self.ExtractFromA].x() self.ExtractAVertex = QgsVertexMarker(canvas) self.ExtractAVertex.setCenter(xform.transform(QgsPointXY(longitude, latitude))) self.ExtractAVertex.setColor(QColor(0,255,0)) self.ExtractAVertex.setIconSize(10) self.ExtractAVertex.setIconType(QgsVertexMarker.ICON_X) self.ExtractAVertex.setPenWidth(10) self.ExtractA = True if self.ExtractB == True: self.pushButtonCut_2.setEnabled(True) else: self.pushButtonCut_2.setEnabled(False) def ExtractToB(self): if self.ExtractB == True: self.Main.iface.mapCanvas().scene().removeItem(self.ExtractBVertex) self.ExtractB = False self.ExtractToB = round((self.player.position()- self.StartMsecond )/1000) if self.ExtractA == True: if self.ExtractToB > self.ExtractFromA: canvas = self.Main.iface.mapCanvas() crsSrc = QgsCoordinateReferenceSystem(4326) # .gpx is in WGS 84 crsDest = QgsProject.instance().crs() xform = QgsCoordinateTransform(crsSrc, crsDest) latitude,longitude = self.Polyline[self.ExtractToB].y(), self.Polyline[self.ExtractToB].x() self.ExtractBVertex = QgsVertexMarker(canvas) self.ExtractBVertex.setCenter(xform.transform(QgsPointXY(longitude, latitude))) self.ExtractBVertex.setColor(QColor(255,0,0)) self.ExtractBVertex.setIconSize(10) self.ExtractBVertex.setIconType(QgsVertexMarker.ICON_X) self.ExtractBVertex.setPenWidth(10) self.ExtractB = True self.pushButtonCut_2.setEnabled(True) else: self.pushButtonCut_2.setEnabled(False) def CancelVertex(self): if self.ExtractA == True: self.Main.iface.mapCanvas().scene().removeItem(self.ExtractAVertex) self.ExtractA = False if self.ExtractB == True: self.Main.iface.mapCanvas().scene().removeItem(self.ExtractBVertex) self.ExtractB = False self.pushButtonCut_2.setEnabled(False) def ExtractToolbar(self): if self.ExtractTool == 0: self.dockWidget_4.show() self.ExtractTool = 1 else: self.dockWidget_4.hide() self.ExtractTool = 0 def transform_wgs84_to_utm(self, lon, lat): def get_utm_zone(longitude): return (int(1+(longitude+180.0)/6.0)) def is_northern(latitude): """ Determines if given latitude is a northern for UTM """ if (latitude < 0.0): return 0 else: return 1 utm_coordinate_system = osr.SpatialReference() utm_coordinate_system.SetWellKnownGeogCS("WGS84") # Set geographic coordinate system to handle lat/lon utm_coordinate_system.SetUTM(get_utm_zone(lon), is_northern(lat)) wgs84_coordinate_system = utm_coordinate_system.CloneGeogCS() # Clone ONLY the geographic coordinate system wgs84_to_utm_transform = osr.CoordinateTransformation(wgs84_coordinate_system, utm_coordinate_system) # (<from>, <to>) return wgs84_to_utm_transform.TransformPoint(lon, lat, 0) # returns easting, northing, altitude
class NewProject(QtWidgets.QWidget, Ui_NewProject): def __init__(self,projectfile,MainWidget): QtWidgets.QWidget.__init__(self) self.setupUi(self) self.setWindowFlags(Qt.WindowStaysOnTopHint) self.Main = MainWidget self.iface = self.Main.iface self.muteButton.setIcon( self.style().standardIcon(QStyle.SP_MediaVolume)) self.replayPlay_pushButton.setIcon( self.style().standardIcon(QStyle.SP_MediaPlay)) if projectfile.split('.')[-1] =="vgp": self.projectfile = projectfile else: self.projectfile = projectfile +'.vgp' self.videofile = None self.GPXfile = None self.GPXList = None self.fps = None self.RealFps = None self.DB = None self.player = QMediaPlayer() self.player.setVideoOutput(self.video_frame_2) self.player.durationChanged.connect(self.durationChanged) self.player.positionChanged.connect(self.positionChanged) self.player.stateChanged.connect(self.mediaStateChanged) self.toolButton_3.clicked.connect(self.ManageDB) self.pushButton_2.clicked.connect(self.Synchronize) self.pushButton.clicked.connect(self.SelectVideoGPX) self.replayPlay_pushButton.clicked.connect(self.PlayPause) self.muteButton.clicked.connect(self.MuteUnmute) self.horizontalSlider.sliderMoved.connect(self.setPosition) self.toolButton.clicked.connect(self.SkipBackward) self.toolButton_2.clicked.connect(self.SkipForward) self.SkipBacktoolButton_7.clicked.connect(self.BackwardFrame) self.SkipFortoolButton_8.clicked.connect(self.ForwardFrame) def closeEvent(self, *args, **kwargs): self.player.stop() return QtWidgets.QWidget.closeEvent(self, *args, **kwargs) def mediaStateChanged(self, state): if self.player.state() == QMediaPlayer.PlayingState: self.replayPlay_pushButton.setIcon( self.style().standardIcon(QStyle.SP_MediaPause)) else: self.replayPlay_pushButton.setIcon( self.style().standardIcon(QStyle.SP_MediaPlay)) def Synchronize(self): TimeItem = self.comboBox.currentIndex() duration = self.player.duration() position = self.player.position() VideoPartLen = round((duration-position) / 1000) GpxPartition = self.GPXList[TimeItem:VideoPartLen+TimeItem] outputFile = open(self.projectfile ,'w') if self.DB == None: outputFile.write('VideoGis Project v0.1 DO NOT MODIFY'+ '\nVideo file location = ' +self.videofile+ '\nVideo start at msecond: '+ str(self.player.position())+ ' #fps = '+str(self.RealFps)+ '\nDB = None'+ '\n'+'Latitude # Longitude # Ele # Speed (m/s) # Course # Time \n') else: outputFile.write('Video file location = ' +self.videofile+ '\nVideo start at msecond: '+ str(self.player.position())+ ' #fps = '+str(self.RealFps)+ '\nDB = '+str(self.DB.dataProvider().dataSourceUri().split('|')[0])+ '\n'+'Latitude # Longitude # Ele # Speed (m/s) # Course # Time \n') Counter = 0 for x in GpxPartition: if Counter != 0: ActualLatitude = x[1][0] ActualLongitude = x[1][1] PreviousLatitude = GpxPartition[Counter-1][1][0] PreviousLongitude = GpxPartition[Counter-1][1][1] GeodesicCalcolus = Geodesic.WGS84.Inverse(PreviousLatitude, PreviousLongitude, ActualLatitude, ActualLongitude) Speed = GeodesicCalcolus['s12'] /1 Course = GeodesicCalcolus['azi2'] if Course < 0: Course += 360 Ele = x[1][2] Time = x[1][3] Counter = Counter + 1 else: ActualLatitude = x[1][0] ActualLongitude = x[1][1] PreviousLatitude = GpxPartition[Counter+1][1][0] PreviousLongitude = GpxPartition[Counter+1][1][1] GeodesicCalcolus = Geodesic.WGS84.Inverse(ActualLatitude, ActualLongitude, PreviousLatitude, PreviousLongitude) Speed = GeodesicCalcolus['s12'] * 1 Course = GeodesicCalcolus['azi2'] if Course < 0: Course += 360 Ele = x[1][2] Time = x[1][3] Counter = Counter + 1 outputFile.write(str(ActualLatitude)+' '+str(ActualLongitude)+' '+str(Ele)+' '+str(Speed)+' '+str(Course)+' '+str(Time)+'\n') outputFile.close() self.Main.LoadProjFromNew(self.projectfile) if os.name == 'nt': os.remove (self.tmp) self.close() def SelectVideoGPX(self): if os.name == 'nt': ffmpeg = os.path.dirname(__file__)+'/FFMPEG/ffmpeg.exe' versione = 'ffmpeg.exe' else: ffmpeg = os.path.dirname(__file__)+'/FFMPEG/./ffmpeg' versione = 'ffmpeg' if os.path.exists(ffmpeg) == True: self.comboBox.clear() if self.player.state() == QMediaPlayer.PlayingState: self.player.pause() self.videofile = None self.GPXfile = None options = QFileDialog.Options() options |= QFileDialog.DontUseNativeDialog self.videofile, _ = QFileDialog.getOpenFileName(self,"Select Video File", "","All Files (*);;Video File (*.mp4 *.avi *.ogv)", options=options) if self.videofile: self.GPXfile, _ = QFileDialog.getOpenFileName(self,"Select GPX file", "","All Files (*);;Video File (*.gpx)", options=options) if self.GPXfile: self.ParseGpx(self.GPXfile) self.LoadVideo(self.videofile) self.replayPosition_label.setText( "-:- / -:-") else: ret = QMessageBox.warning(self, "Warning", 'missing ffmpeg binaries, please download it from https://github.com/sagost/VideoUavTracker/blob/master/FFMPEG/'+versione+' and paste it in /.qgis3/python/plugins/Video_UAV_Tracker/FFMPEG/ ', QMessageBox.Ok) self.close() def ParseGpx(self,GPXfile): gpx = parse(GPXfile) track = gpx.getElementsByTagName("trkpt") GPXList = [] Error = 0 GpxProgressiveNumber = 0 Timestamp = 'Segnaposto' for name in track: dict = {'Lat': 0, 'Lon': 0, 'Ele': 0, 'Time':0} a = (name.toprettyxml(indent = '') ).split() for x in a: if x.find('lat') == 0: lat = float(x.split('"')[1]) dict['Lat'] = float(x.split('"')[1]) elif x.find('lon') == 0: lon = float(x.split('"')[1]) dict['Lon'] = float(x.split('"')[1]) elif x.find('<ele>') == 0: dict['Ele'] = float(x[5:-6]) elif x.find('<time>') == 0: try: gpxtime = time.strftime('%Y-%m-%dT%H:%M:%S.%fZ',time.strptime(x[6:-7], '%Y-%m-%dT%H:%M:%S.%fZ')) dict['Time']= x[6:-7] except ValueError: try: gpxtime = time.strftime('%Y-%m-%dT%H:%M:%SZ',time.strptime(x[6:-7],'%Y-%m-%dT%H:%M:%SZ')) dict['Time']= x[6:-7] except ValueError: try: gpxtime = time.strftime('%Y-%m-%dT%H:%M:%S',time.strptime(x[6:-7],'%Y-%m-%dT%H:%M:%S')) dict['Time']= x[6:-7] except ValueError: try: gpxtime = time.strftime('%Y-%m-%dT%H.%M.%S',time.strptime(x[6:-7],'%Y-%m-%dT%H.%M.%S')) dict['Time']= x[6:-7] except ValueError: try: gpxtime = time.strftime('%Y-%m-%dT%H.%M.%S',time.strptime(x[6:-13],'%Y-%m-%dT%H.%M.%S')) dict['Time']= x[6:-13] except ValueError: try: gpxtime = time.strftime('%Y-%m-%dT%H.%M.%S',time.strptime(x[6:-13],'%Y-%m-%dT%H:%M:%S')) dict['Time']= x[6:-13] except ValueError: Error = 1 FormatoErrore = str(x) if dict['Time'] != Timestamp: Point = [dict['Lat'],dict['Lon'],dict['Ele'],dict['Time']] self.comboBox.addItem(str(GpxProgressiveNumber) + '-'+gpxtime ) GPXList.append([GpxProgressiveNumber,Point]) GpxProgressiveNumber = GpxProgressiveNumber + 1 Timestamp = dict['Time'] else: Timestamp = dict['Time'] if Error == 0: self.GPXList = GPXList else: ret = QMessageBox.warning(self, "Warning", FormatoErrore +' UNKOWN GPX TIME FORMAT - ABORTED', QMessageBox.Ok) self.close def LoadVideo(self,videofile): fps = self.getVideoDetails(str(videofile)) self.RealFps = float(fps) self.fps = (1 / self.RealFps )*1000 url = QUrl.fromLocalFile(str(self.videofile)) mc = QMediaContent(url) self.player.setMedia(mc) self.player.play() def setPosition(self, position): self.player.setPosition(position*1000) def durationChanged(self, duration): duration /= 1000 self.horizontalSlider.setMaximum(duration) def secTotime(self,seconds): m, s = divmod(seconds, 60) h, m = divmod(m, 60) return "%d:%02d:%02d" % (h, m, s) def positionChanged(self, progress): duration = self.player.duration() totalTime = self.secTotime(duration/1000) actualTime = self.secTotime(progress/1000) self.replayPosition_label.setText(actualTime + ' / '+totalTime) progress /= 1000 if not self.horizontalSlider.isSliderDown(): self.horizontalSlider.setValue(progress) def MuteUnmute(self): if self.player.mediaStatus() == 6 : if self.player.isMuted() == 1: self.player.setMuted(0) self.muteButton.setIcon( self.style().standardIcon(QStyle.SP_MediaVolume)) elif self.player.isMuted() == 0: self.player.setMuted(1) self.muteButton.setIcon( self.style().standardIcon(QStyle.SP_MediaVolumeMuted)) def PlayPause(self): if self.player.state() == QMediaPlayer.PlayingState: self.player.pause() else: self.player.play() def getVideoDetails(self,filepath): if os.name == 'nt': tmp = os.path.dirname(__file__)[0:-18]+'/Video_UAV_Tracker/tmp' tmp2 = '"'+tmp+'"' filepath2 = '"'+filepath+'"' a = open(tmp,'w') a.close() ffmpeg = '"'+os.path.dirname(__file__)[0:-18]+'/Video_UAV_Tracker/FFMPEG/ffmpeg.exe'+'"' a = os.popen(str(ffmpeg + ' -i '+filepath2+' 2> '+tmp2)) while os.stat(tmp).st_size < 1500: pass a = open(tmp,'r') lines = a.readlines() a.close() for l in lines: l = l.strip() if str(l).startswith("Stream #0:0"): linea = str(l).split(',')[-4] dopo = linea.find('fps') fps = float(linea[0:dopo]) self.tmp = tmp return fps else: tmpf = tempfile.NamedTemporaryFile() ffmpeg = os.path.dirname(__file__)+'/FFMPEG/./ffmpeg' os.system(str(ffmpeg)+" -i \"%s\" 2> %s" % (filepath, tmpf.name)) lines = tmpf.readlines() tmpf.close() for l in lines: l = l.strip() if str(l).startswith("b'Stream #0:0"): linea = str(l).split(',')[-4] dopo = linea.find('fps') fps = float(linea[0:dopo]) return fps def SkipForward(self): position = self.player.position() self.player.setPosition(position+1000) def SkipBackward(self): position = self.player.position() self.player.setPosition(position-1000) def ForwardFrame(self): position = self.player.position() self.player.setPosition(position+int(self.fps)) def BackwardFrame(self): position = self.player.position() self.player.setPosition(position-int(self.fps)) def ManageDB(self): self.player.pause() shapeFileFirst,_ = QFileDialog.getSaveFileName(caption = 'Save shape file', filter = "Esri shp (*.shp)") if shapeFileFirst: if shapeFileFirst.split('.')[-1] == 'shp': shapeFile = shapeFileFirst else: shapeFile = shapeFileFirst + '.shp' try: os.remove(shapeFile) os.remove(shapeFileFirst.split('.')[0]+'.qpg') os.remove(shapeFileFirst.split('.')[0]+'.prj') os.remove(shapeFileFirst.split('.')[0]+'.cpg') os.remove(shapeFileFirst.split('.')[0]+'.shx') os.remove(shapeFileFirst.split('.')[0]+'.dbf') except OSError: pass crs = QgsCoordinateReferenceSystem(4326, QgsCoordinateReferenceSystem.EpsgCrsId) fields = QgsFields() QgsVectorFileWriter(shapeFile, "CP1250", fields, QgsWkbTypes.Point, crs, "ESRI Shapefile") EmptyLayer = QgsVectorLayer(shapeFile, shapeFile.split('.')[0].split('/')[-1], 'ogr') self.dialoga = TableManager(self.iface, EmptyLayer,self) self.dialoga.exec_() def AcceptNewDB(self,DB): self.DB = DB
class PlaybackPanel(SpecialLabel): desktop_lyric_state_changed_signal = pyqtSignal(bool) playmode_changed_signal = pyqtSignal(int, int) media_player_notify_signal = pyqtSignal(int) muted_changed_signal = pyqtSignal(int) mark_favorite_completed_signal = pyqtSignal() current_media_changed_signal = pyqtSignal() music_ended_signal = pyqtSignal() update_window_lyric_signal = pyqtSignal(str, str) show_artist_info_signal = pyqtSignal(str) dont_hide_main_window_signal = pyqtSignal() def __init__(self, parent=None): super(PlaybackPanel, self).__init__(parent) self.initial_mediaplayer() self.create_actions() self.setup_ui() self.create_connections() self.initial_params() def create_connections(self): self.artistHeadLabel.clicked.connect(self.show_artist_info) self.desktopLyric.hide_desktop_lyric_signal.connect(self.desktop_lyric_closed) self.seekSlider.valueChanged.connect(self.slider_value_changed) self.seekSlider.sliderPressed.connect(self.slider_pressed) self.seekSlider.sliderReleased.connect(self.seek) self.mediaPlayer.positionChanged.connect(self.tick) self.mediaPlayer.mutedChanged.connect(self.muted_changed_signal.emit) self.mediaPlayer.stateChanged.connect(self.state_changed) self.mediaPlayer.durationChanged.connect(self.duration_changed) self.mediaPlayer.mediaStatusChanged.connect(self.media_status_changed) self.mediaPlayer.currentMediaChanged.connect(self.current_media_changed) def initial_mediaplayer(self): self.mediaPlayer = QMediaPlayer() self.mediaPlayer.setNotifyInterval(500) self.set_volume(globalSettings.Volume) def initial_params(self): self.playlist = None self.artistName = "Zheng-Yejian" self.clickPlayFlag = False # 用来标志一首歌是否是主动点击选中的 self.timerFlag = False self.timeStart = 0 self.timeSpan = 0 self.sourcePath = "" self.errorType = Configures.NoError self.currentSourceRow = -1 self.nearPlayedSongs = [] self.downloadDir = globalSettings.DownloadfilesPath self.songinfosManager = SonginfosManager() self.totalTime = Configures.ZeroTime self.playmode = Configures.PlaymodeRandom # 播放模式指示器 playlistTemp = Playlist() playlistTemp.fill_list(Configures.PlaylistFavorite) self.lovedSongs = playlistTemp.get_titles() def set_playlist(self, playlist): self.playlist = playlist self.currentSourceRow = self.playlist.get_current_row() def create_actions(self): self.nextAction = QAction(QIcon(IconsHub.ControlNext), "下一首", self, enabled=True, triggered=self.next_song) self.playAction = QAction(QIcon(IconsHub.ControlPlay), "播放/暂停", self, enabled=True, triggered=self.play_music) self.previousAction = QAction( QIcon(IconsHub.ControlPrevious), "上一首", self, enabled=True, triggered=self.previous_song ) self.stopAction = QAction( QIcon(IconsHub.ControlStop), "停止", self, enabled=True, triggered=self.stop_music_but_timing ) def get_play_button_action(self): return self.playAction def get_previous_button_action(self): return self.previousAction def get_next_button_action(self): return self.nextAction def get_stop_button_action(self): return self.stopAction def set_download_dir(self, dir): self.downloadDir = dir def get_loved_songs(self): return self.lovedSongs def get_songinfos_manager(self): return self.songinfosManager def setup_ui(self): self.setFixedHeight(50) # 桌面歌词标签 self.desktopLyric = desktop_lyric.DesktopLyric() self.desktopLyric.set_color(globalSettings.DesktoplyricColors) # 3个标签 self.artistHeadLabel = LabelButton() self.artistHeadLabel.setToolTip(self.tr("查看歌手信息")) self.artistHeadLabel.setFixedSize(QSize(42, 42)) self.artistHeadLabel.setScaledContents(True) self.artistHeadLabel.setPixmap(QPixmap(IconsHub.Anonymous)) self.musicTitleLabel = NewLabel() self.musicTitleLabel.setObjectName("musicTitleLabel") self.musicTitleLabel.setFixedSize(QSize(370, 20)) self.musicTitleLabel.setText("Zheng-Yejian._.XYPLAYER") self.timeLabel = QLabel("00:00/00:00") self.timeLabel.setObjectName("timeLabel") self.timeLabel.setFixedHeight(20) self.timeLabel.setAlignment(Qt.AlignRight and Qt.AlignVCenter) # 五个基本按键 self.playmodeButton = QToolButton(clicked=self.change_playmode) self.playmodeButton.setFocusPolicy(Qt.NoFocus) self.playmodeButton.setIcon(QIcon(IconsHub.PlaymodeRandom)) self.playmodeButton.setIconSize(QSize(25, 25)) self.playmodeButton.setToolTip("随机播放") self.favoriteButton = QToolButton(clicked=self.mark_as_favorite) self.favoriteButton.setFocusPolicy(Qt.NoFocus) self.favoriteButton.setToolTip("收藏") self.favoriteButton.setIcon(QIcon(IconsHub.Favorites)) self.favoriteButton.setIconSize(QSize(20, 20)) self.previousButton = QToolButton() self.previousButton.setFocusPolicy(Qt.NoFocus) self.previousButton.setIconSize(QSize(40, 40)) self.previousButton.setShortcut(QKeySequence("Ctrl + Left")) self.previousButton.setDefaultAction(self.previousAction) self.playButton = QToolButton() self.playButton.setFocusPolicy(Qt.NoFocus) self.playButton.setIconSize(QSize(40, 40)) self.playButton.setShortcut(QKeySequence("Ctrl + Down")) self.playButton.setDefaultAction(self.playAction) self.nextButton = QToolButton() self.nextButton.setFocusPolicy(Qt.NoFocus) self.nextButton.setIconSize(QSize(40, 40)) self.nextButton.setFocusPolicy(Qt.NoFocus) self.nextButton.setShortcut(QKeySequence("Ctrl + Right")) self.nextButton.setDefaultAction(self.nextAction) self.desktopLyricButton = QToolButton(clicked=self.show_desktop_lyric) self.desktopLyricButton.setToolTip(self.tr("桌面歌词")) self.desktopLyricButton.setFocusPolicy(Qt.NoFocus) self.desktopLyricButton.setIcon(QIcon(IconsHub.DesktopLyric)) self.desktopLyricButton.setIconSize(QSize(25, 25)) self.seekSlider = QSlider(Qt.Horizontal) self.seekSlider.setObjectName("seekSlider") self.seekSlider.setFixedHeight(20) self.seekSlider.setFocusPolicy(Qt.NoFocus) self.seekSlider.setRange(0, 0) hbox1 = QHBoxLayout() hbox1.addWidget(self.favoriteButton) hbox1.addWidget(self.musicTitleLabel) hbox1.addStretch() hbox1.addWidget(self.timeLabel) vbox1 = QVBoxLayout() vbox1.addLayout(hbox1) vbox1.setSpacing(5) vbox1.addWidget(self.seekSlider) mainLayout = QHBoxLayout(self) mainLayout.setContentsMargins(2, 0, 0, 0) mainLayout.addWidget(self.artistHeadLabel) mainLayout.addWidget(self.previousButton) mainLayout.addWidget(self.playButton) mainLayout.addWidget(self.nextButton) mainLayout.addLayout(vbox1) mainLayout.addWidget(self.playmodeButton) mainLayout.addWidget(self.desktopLyricButton) def show_desktop_lyric(self): if self.desktopLyric.isHidden(): beToOff = True self.desktopLyric.show() self.desktopLyric.original_place() else: beToOff = False self.desktopLyric.hide() self.desktop_lyric_state_changed_signal.emit(beToOff) def desktop_lyric_closed(self): self.desktop_lyric_state_changed_signal.emit(False) def change_playmode(self): oldPlaymode = self.playmode if self.playmode == Configures.PlaymodeRandom: self.set_new_playmode(Configures.PlaymodeOrder) elif self.playmode == Configures.PlaymodeOrder: self.set_new_playmode(Configures.PlaymodeSingle) elif self.playmode == Configures.PlaymodeSingle: self.set_new_playmode(Configures.PlaymodeRandom) self.playmode_changed_signal.emit(oldPlaymode, self.playmode) def set_new_playmode(self, playmode): self.playmode = playmode if playmode == Configures.PlaymodeRandom: iconPath = IconsHub.PlaymodeRandom toolTip = Configures.PlaymodeRandomText elif playmode == Configures.PlaymodeOrder: iconPath = IconsHub.PlaymodeOrder toolTip = Configures.PlaymodeOrderText else: iconPath = IconsHub.PlaymodeSingle toolTip = Configures.PlaymodeSingleText self.playmodeButton.setIcon(QIcon(iconPath)) self.playmodeButton.setToolTip(toolTip) def ui_initial(self): self.mediaPlayer.stop() self.totalTime = "00:00" self.playAction.setIcon(QIcon(IconsHub.ControlPlay)) self.musicTitleLabel.setText("Zheng-Yejian._.XYPLAYER") self.artistName = "Zheng-Yejian" self.artistHeadLabel.setPixmap(QPixmap(IconsHub.Anonymous)) self.seekSlider.setRange(0, 0) self.favoriteButton.setIcon(QIcon(IconsHub.Favorites)) self.favoriteButton.setToolTip("收藏") self.timeLabel.setText("00:00/00:00") def set_volume(self, volume): self.mediaPlayer.setVolume(volume) def set_muted(self, muted): self.mediaPlayer.setMuted(muted) def tick(self): currentTime = self.mediaPlayer.position() self.seekSlider.setValue(currentTime) cTime = format_position_to_mmss(currentTime // 1000) self.timeLabel.setText(cTime + "/" + self.totalTime) self.media_player_notify_signal.emit(currentTime) def slider_value_changed(self, value): cTime = format_position_to_mmss(value // 1000) self.timeLabel.setText("%s/%s" % (cTime, self.totalTime)) self.media_player_notify_signal.emit(value) def slider_pressed(self): self.mediaPlayer.positionChanged.disconnect(self.tick) def seek(self): if self.mediaPlayer.state() == QMediaPlayer.StoppedState: self.mediaPlayer.play() self.mediaPlayer.setPosition(self.seekSlider.value()) else: self.mediaPlayer.setPosition(self.seekSlider.value()) self.mediaPlayer.play() self.mediaPlayer.positionChanged.connect(self.tick) def duration_changed(self, duration): self.seekSlider.setMaximum(duration) exactTotalTime = format_position_to_mmss(self.mediaPlayer.duration() // 1000) self.timeLabel.setText("%s/%s" % (Configures.ZeroTime, exactTotalTime)) if self.totalTime != exactTotalTime: self.totalTime = exactTotalTime self.playlist.set_music_time_at(self.currentSourceRow, exactTotalTime) def check_favorite(self): if self.currentSourceRow >= 0: if self.playlist.get_music_title_at(self.currentSourceRow) in self.lovedSongs: self.favoriteButton.setIcon(QIcon(IconsHub.Favorites)) self.favoriteButton.setToolTip("取消收藏") else: self.favoriteButton.setIcon(QIcon(IconsHub.FavoritesNo)) self.favoriteButton.setToolTip("收藏") if self.playlist.get_name() == Configures.PlaylistFavorite: self.favoriteButton.setToolTip("收藏") def mark_as_favorite(self): if ( self.playlist.get_name() == Configures.PlaylistFavorite or not self.playlist.length() or self.currentSourceRow < 0 ): return path = self.playlist.get_music_path_at(self.currentSourceRow) title = self.playlist.get_music_title_at(self.currentSourceRow) if self.playlist.get_name() == Configures.PlaylistOnline: musicName = get_full_music_name_from_title(title) musicPath = os.path.join(self.downloadDir, musicName) musicPathO = os.path.join(Configures.MusicsDir, musicName) if not os.path.exists(musicPath) and not os.path.exists(musicPathO): QMessageBox.information(self, "提示", "请先下载该歌曲再添加喜欢!") return if os.path.exists(musicPath): path = musicPath else: path = musicPathO elif not os.path.exists(path): QMessageBox.information(self, "提示", "路径'" + "%s" % path + "'无效,无法标记喜欢!") return playlistTemp = Playlist() playlistTemp.fill_list(Configures.PlaylistFavorite) if title in self.lovedSongs: playlistTemp.remove_item_at(self.lovedSongs.index(title)) playlistTemp.commit_records() self.lovedSongs.remove(title) self.favoriteButton.setIcon(QIcon(IconsHub.FavoritesNo)) self.favoriteButton.setToolTip("收藏") else: playlistTemp.add_item_from_path(path) playlistTemp.commit_records() self.lovedSongs.append(title) self.favoriteButton.setIcon(QIcon(IconsHub.Favorites)) self.favoriteButton.setToolTip("取消收藏") self.mark_favorite_completed_signal.emit() def show_artist_info(self): if self.artistName: self.show_artist_info_signal.emit(self.artistName) def decide_to_play_or_pause(self, row): if row != self.currentSourceRow: self.set_media_source_at_row(row, clickPlayFlag=True) elif self.mediaPlayer.state() in (QMediaPlayer.PausedState, QMediaPlayer.StoppedState): self.mediaPlayer.play() elif self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.mediaPlayer.pause() def set_media_source_at_row(self, row, clickPlayFlag=False): if not self.playlist.length() or row < 0: return self.stop_music() self.clickPlayFlag = clickPlayFlag self.playlist.set_current_row(row) sourcePath = self.playlist.get_music_path_at(row) self.title = self.playlist.get_music_title_at(row) self.sourceTrace = "local" if self.playlist.get_music_id_at(row) == Configures.LocalMusicId else "online" self.artistName, self.musicName = get_artist_and_musicname_from_title(self.title) self.playlistName = self.playlist.get_name() self.totalTime = self.playlist.get_music_time_at(row) self.album = self.playlist.get_music_album_at(row) self.errorType = Configures.NoError isAnUrl = False if not os.path.exists(sourcePath): if self.playlist.get_name() == Configures.PlaylistOnline: if sourcePath == Configures.NoLink: musicId = self.playlist.get_music_id_at(row) sourcePath = SearchOnline.get_song_link(musicId) if sourcePath: self.playlist.set_music_path_at(row, sourcePath) else: self.errorType = Configures.UrlError isAnUrl = True else: self.errorType = Configures.PathError sourcePath = "/usr/share/sounds/error_happened.ogg" if self.errorType == Configures.NoError: self.sourcePath = sourcePath self.musicFileName = get_base_name_from_path(sourcePath) self.playedDate = get_time_of_now() self.songinfosManager.update_datas_of_item( self.musicFileName, self.playedDate, self.musicName, self.artistName, self.totalTime, self.album, self.playlistName, ) if not self.timerFlag: self.timerFlag = True self.timeSpan = 0 if isAnUrl: url = QUrl(sourcePath) else: url = QUrl.fromLocalFile(sourcePath) self.play_from_url(url) else: self.timerFlag = False self.dont_hide_main_window_signal.emit() if self.errorType == Configures.DisnetError: QMessageBox.critical( self, "错误", "联网出错!\n无法联网播放歌曲'%s'!\n您最好在网络畅通时下载该曲目!" % self.playlist.get_music_title_at(row) ) elif self.errorType == Configures.PathError: QMessageBox.information(self, "提示", "路径'%s'无效,请尝试重新下载并添加对应歌曲!" % self.playlist.get_music_path_at(row)) def play_from_url(self, url): mediaContent = QMediaContent(url) self.mediaPlayer.setMedia(mediaContent) self.mediaPlayer.play() def state_changed(self, newState): if self and newState in [QMediaPlayer.PlayingState, QMediaPlayer.PausedState, QMediaPlayer.StoppedState]: if not self.playlist.length(): return iconPath = IconsHub.ControlPause if newState in [QMediaPlayer.StoppedState, QMediaPlayer.PausedState]: iconPath = IconsHub.ControlPlay icon = QIcon(iconPath) self.playAction.setIcon(icon) if self.timerFlag: if newState == QMediaPlayer.PlayingState: self.timeStart = time.time() else: self.timeSpan += time.time() - self.timeStart def media_status_changed(self, status): if status == QMediaPlayer.EndOfMedia: self.music_finished() def music_finished(self): if self.errorType == Configures.NoError: self.next_song() def play_music(self): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.mediaPlayer.pause() else: self.mediaPlayer.play() def stop_music_but_timing(self): self.mediaPlayer.stop() self.seekSlider.setValue(0) self.media_player_notify_signal.emit(-0.5) def stop_music(self): self.stop_music_but_timing() if self.timerFlag: self.timerFlag = False InfosList = [ self.playedDate, self.musicFileName, self.musicName, self.artistName, self.album, "%i" % change_mmss_to_seconds(self.totalTime), "%.1f" % self.timeSpan, self.playlistName, self.sourcePath, "%i" % (self.title in self.lovedSongs), self.sourceTrace, Configures.Playmodes[self.playmode], "%i" % self.clickPlayFlag, ] log_playback_history(organized_list_as_str(InfosList)) self.songinfosManager.update_time_span_relate_of_item(self.musicFileName, self.timeSpan, self.clickPlayFlag) self.clickPlayFlag = False def get_next_random_row(self): listTemp = list(self.playlist.get_ids() - set(self.nearPlayedSongs)) ran = random.randint(0, len(listTemp) - 1) return self.playlist.get_items_queue().index(listTemp[ran]) def get_next_single_row(self): nextRow = self.currentSourceRow if nextRow < 0: nextRow = 0 return nextRow def get_next_order_row(self, reverse=False): if reverse: if self.currentSourceRow < 0: self.currentSourceRow = 0 return (self.currentSourceRow - 1) % self.playlist.length() return (self.currentSourceRow + 1) % self.playlist.length() def previous_song(self): self.play_source_on_next_row(reverse=True) def next_song(self): self.play_source_on_next_row() def play_source_on_next_row(self, reverse=False): if not self.playlist.length(): return if self.mediaPlayer.position() > 20: self.music_ended_signal.emit() nextRow = 0 if self.playmode == Configures.PlaymodeRandom: nextRow = self.get_next_random_row() elif self.playmode == Configures.PlaymodeOrder: nextRow = self.get_next_order_row(reverse) elif self.playmode == Configures.PlaymodeSingle: nextRow = self.get_next_single_row() self.set_media_source_at_row(nextRow) def current_media_changed(self): if not self.playlist.length(): return self.current_media_changed_signal.emit() self.update_parameters() self.update_near_played_queue() self.check_favorite() def update_parameters(self): self.currentSourceRow = self.playlist.get_current_row() self.musicTitleLabel.setText(self.title) self.playAction.setText(self.musicName) imagePath = SearchOnline.get_artist_image_path(self.artistName) if imagePath: pixmap = QPixmap(imagePath) else: pixmap = QPixmap(IconsHub.Anonymous) self.artistHeadLabel.setPixmap(pixmap) musicId = self.playlist.get_music_id_at(self.currentSourceRow) self.update_window_lyric_signal.emit(self.title, musicId) def update_near_played_queue(self): self.currentSourceId = self.playlist.get_music_path_at(self.currentSourceRow) if self.playlist.get_name() == Configures.PlaylistOnline: self.currentSourceId = self.playlist.get_music_id_at(self.currentSourceRow) if self.currentSourceId not in self.nearPlayedSongs: self.nearPlayedSongs.append(self.currentSourceId) while len(self.nearPlayedSongs) >= self.playlist.length() * 4 / 5: del self.nearPlayedSongs[0] def add_title_into_loved_songs(self, title): self.lovedSongs.append(title)
import sys from PyQt5.QtWidgets import QApplication from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent from PyQt5.QtCore import QUrl if __name__ == '__main__': app = QApplication(sys.argv) path = '/home/zetta/音乐/周柏豪._.哦.mp3' mediaContent = QMediaContent(QUrl.fromLocalFile(path)) player = QMediaPlayer() player.setMedia(mediaContent) player.play() sys.exit(app.exec_())
class GameWindow(QWidget): def __init__(self, parent=None): super(GameWindow,self).__init__(parent) self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.videoWidget = QVideoWidget() self.mediaPlayer.setVideoOutput(self.videoWidget) self.stringLabel = QLabel() self.stringLabel.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum) self.stringLabel.setTextFormat(Qt.RichText) self.stringLabel.setAlignment(Qt.AlignHCenter) layout = QVBoxLayout() layout.addWidget(self.videoWidget) layout.addWidget(self.stringLabel) self.setLayout(layout) self.mediaPlayer.positionChanged.connect(self.positionChanged) def openFile(self, fileName): if fileName != '': self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile(fileName))) def play(self): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.mediaPlayer.pause() else: self.mediaPlayer.play() def playV(self, file, rate, visibility, labelString): self.position = 0 self.startPos = 0 self.duration = 0 self.durChanged = False self.stopPos = False self.openFile(file) self.mediaPlayer.setPlaybackRate(rate) if visibility: self.videoWidget.show() self.stringLabel.show() self.stringLabel.setText(labelString) else: self.videoWidget.hide() self.stringLabel.show() self.stringLabel.setText(labelString) self.play() def closeEvent(self, event): event.ignore() self.mediaPlayer.stop() super(GameWindow, self).closeEvent(event) def positionChanged(self, pos): self.position = pos if not self.durChanged and self.position > 0: self.durationChanged(self.mediaPlayer.duration()) self.durChanged = True if self.startPos > 0 and not self.stopPos and not self.videoWidget.isVisible(): if self.position > self.startPos + 20000: self.play() self.stopPos = True def durationChanged(self, dur): self.duration = dur if self.duration > 40000 and not self.videoWidget.isVisible(): self.startPos = random.randint(5000, self.duration - 25000) self.mediaPlayer.setPosition(self.startPos) def showPoints(self, pointsString): self.videoWidget.hide() self.stringLabel.show() self.stringLabel.setText(pointsString)
class Controller: def __init__(self, view, log): self.log = log self.view = view self._player = QMediaPlayer() self._player.mediaStatusChanged.connect(self._player_status_changed) self._player.mediaChanged.connect(self._player_media_changed) self._player.currentMediaChanged.connect(self._player_current_media_changed) self._player.stateChanged.connect(self._player_state_changed) self._player.positionChanged.connect(self._player_position_changed) self._player.durationChanged.connect(self._player_duration_changed) self._searched_tracks = [] self.playlists = [] self.playing_playlist = 0 self.last_colored_item = None def _player_status_changed(self, status): self.log.debug('_player_status_changed: %s', str(status)) if status in [QMediaPlayer.EndOfMedia, QMediaPlayer.InvalidMedia]: self.next() if status in [QMediaPlayer.EndOfMedia, QMediaPlayer.NoMedia, QMediaPlayer.UnknownMediaStatus, QMediaPlayer.InvalidMedia]: self.view.set_title() else: try: pos = self.playlists[self.playing_playlist].active_track if pos >= 0: track = self.playlists[self.playing_playlist].tracks[pos] self.view.set_title(track.title) self.update_list_position(pos) except IndexError: self.log.error('Index error in _player_status_changed') def _player_media_changed(self, media): self.log.debug('_player_media_changed: %s' % str(media)) def _player_current_media_changed(self, media): self.log.debug('_player_current_media_changed: %s' % str(media)) def _player_state_changed(self, state): self.log.debug('_player_state_changed: %s' % str(state)) def _player_duration_changed(self, duration): self.log.debug('_player_duration_changed: %s' % str(duration)) self.view.track_position.setMaximum(duration) def _player_position_changed(self, pos): self.view.track_position.setValue(pos) def volume_changed(self, value): self._player.setVolume(value) def update_status(self): total_duration = 0 playlist_index = self.view.tabs.currentIndex() for track in self.playlists[playlist_index].tracks: total_duration += track.duration self.view.playlist_status.setText("%i tracks. Total duration %i:%02i:%02i:%02i" % (self.playlists[playlist_index].count(), total_duration // 86400, total_duration // 3600 % 24, total_duration // 60 % 60, total_duration % 60)) def add_track(self, track, playlist_index=None): if playlist_index is None: playlist_index = self.view.tabs.currentIndex() self.playlists[playlist_index].add(track) self.view.tabs.widget(playlist_index).addItem(track.title) def remove_track(self, track_pos=None): if track_pos is None: track_pos = self.view.tabs.currentWidget().currentRow() if track_pos != -1: self.view.tabs.currentWidget().takeItem(track_pos) playlist_index = self.view.tabs.currentIndex() self.playlists[playlist_index].remove(track_pos) self.update_status() def remove_all_tracks(self): playlist_index = self.view.tabs.currentIndex() self.playlists[playlist_index].clear() self.view.tabs.currentWidget().clear() self.update_status() def next(self): self.log.debug('next') # if we close last tab with current track, after it ended, we stop playing # todo: need check, that if we close not last tab with current song, we also need stop after song ended if self.playing_playlist >= len(self.playlists): return next_pos = self.playlists[self.playing_playlist].get_next_track(shuffle=bool(self.view.shuffle.checkState())) if next_pos is not None: self.playlists[self.playing_playlist].active_track = next_pos url = self.playlists[self.playing_playlist].tracks[next_pos].stream_url() self._player.setMedia(QMediaContent(QUrl(url))) self.play() def previous(self): self.log.debug('previous') prev_pos = self.playlists[self.playing_playlist].get_prev_track(shuffle=bool(self.view.shuffle.checkState())) if prev_pos is not None: self.playlists[self.playing_playlist].active_track = prev_pos url = self.playlists[self.playing_playlist].tracks[prev_pos].stream_url() self._player.setMedia(QMediaContent(QUrl(url))) self.play() def play(self): self.log.debug('play') self._player.play() def pause(self): self.log.debug('pause') self._player.pause() def update_list_position(self, position): showed_list = self.view.tabs.currentWidget() if self.last_colored_item: self.last_colored_item.setBackground(QBrush()) if (position >= 0) and (position <= showed_list.count()): self.last_colored_item = showed_list.item(position) self.last_colored_item.setBackground(QBrush(QColor('red'))) def change_track(self): self.log.debug('change_track') playlist_index = self.view.tabs.currentIndex() self.playing_playlist = playlist_index position = self.view.tabs.currentWidget().currentRow() self.playlists[self.playing_playlist].active_track = position self.log.debug('position: %i' % position) url = self.playlists[self.playing_playlist].tracks[position].stream_url() self._player.setMedia(QMediaContent(QUrl(url))) if self._player.state() in [QMediaPlayer.StoppedState, QMediaPlayer.PausedState]: self.play() def change_track_position(self): self._player.setPosition(self.view.track_position.value()) def remove_dublicates(self): selected_playlist = self.view.tabs.currentIndex() playlist = self.playlists[selected_playlist] processed_ids = [] position_for_removing = [] for index in range(len(playlist.tracks)): if playlist.tracks[index].id in processed_ids: position_for_removing.append(index) else: processed_ids.append(playlist.tracks[index].id) self.log.debug('tracks count: %i' % len(playlist.tracks)) counter = 0 for index in reversed(position_for_removing): self.log.debug('track index for removing: %i' % index) self.remove_track(track_pos=index) counter += 1 self.log.info('Removed %i tracks.' % counter) def save_track(self, playlist_pos=None, track_pos=None): if track_pos is None: track_pos = self.view.tabs.currentWidget().currentRow() if playlist_pos is None: playlist_pos = self.view.tabs.currentIndex() playlist = self.playlists[playlist_pos] track = playlist.tracks[track_pos] track.save() def download_playlist(self): selected_playlist = self.view.tabs.currentIndex() playlist = self.playlists[selected_playlist] for track_pos in range(playlist.count()): self.log.info('Saving %i/%s track...' % (track_pos+1, playlist.count())) self.save_track(playlist_pos=selected_playlist, track_pos=track_pos) self.log.info('Saving done.') def load_playlist(self): playlist_index = self.view.tabs.currentIndex() playlist = self.playlists[playlist_index] loaded_playlist = sc_load_playlist(playlist.name) if not loaded_playlist: self.log.error('Playlist not exists.') return self.remove_all_tracks() for track in loaded_playlist: self.add_track(track) self.update_status() def save_playlist(self): playlist_index = self.view.tabs.currentIndex() playlist = self.playlists[playlist_index] sc_save_playlist(playlist.name, playlist) def add_playlist(self, name): self.playlists.append(Playlist(name)) def remove_playlist(self, index): self.log.debug('remove playlist with index = %i' % index) del (self.playlists[index]) def search_tracks(self): self.view.search_list.clear() tracks = sc_search_tracks(self.view.input.text()) self._searched_tracks = tracks total_duration = 0 for track in self._searched_tracks: self.view.search_list.addItem(track.title) total_duration += track.duration self.view.search_status.setText("Founded %i tracks. Total duration %i:%02i:%02i:%02i" % (len(self._searched_tracks), total_duration // 86400000, total_duration // 3600000 % 24, total_duration // 60000 % 60, total_duration // 1000 % 60)) def search_similar(self): self.view.search_list.clear() position = self.view.tabs.currentWidget().currentRow() playlist_index = self.view.tabs.currentIndex() track = self.playlists[playlist_index].tracks[position] related_tracks = track.search_related() self._searched_tracks = related_tracks total_duration = 0 for track in self._searched_tracks: self.view.search_list.addItem(track.title) total_duration += track.duration self.view.search_status.setText("Founded %i tracks. Total duration %i:%02i:%02i:%02i" % (len(self._searched_tracks), total_duration // 86400000, total_duration // 3600000 % 24, total_duration // 60000 % 60, total_duration // 1000 % 60)) def clicked_add_track(self): position = self.view.search_list.currentRow() self.add_track(self._searched_tracks[position]) def clicked_add_all_tracks(self): for row in range(self.view.search_list.count()): self.add_track(self._searched_tracks[row]) def load_current_state(self): if not os.path.isfile('state.pickle'): return f = open('state.pickle', 'rb') state = pickle.load(f) f.close() loaded_playlists = state['playlists'] self.log.debug('loaded %i playlists.' % len(loaded_playlists)) for i in range(len(loaded_playlists) - len(self.playlists)): self.view.tab_add() self.playlists.clear() index = 0 for playlist in loaded_playlists: self.log.debug('playlist: %s, len: %i' % (playlist.name, len(playlist.tracks))) self.add_playlist(playlist.name) for track in playlist.tracks: self.add_track(track, playlist_index=index) index += 1 self.log.debug(len(self.playlists)) self.log.debug('curent tab: %i' % state['current_playlist']) self.view.tabs.setCurrentIndex(state['current_playlist']) self.log.debug('volume: %i' % state['volume']) self.view.volume.setValue(state['volume']) self.view.shuffle.setCheckState(state['shuffle']) def save_current_state(self): state = dict() self.log.debug('playlists count: %i' % len(self.playlists)) state['playlists'] = self.playlists state['current_playlist'] = self.view.tabs.currentIndex() state['volume'] = self.view.volume.value() state['shuffle'] = self.view.shuffle.checkState() f = open('state.pickle', 'wb') pickle.dump(state, f) f.close()
class Main(QWidget): """主窗口。""" def __init__(self, parent=None): super(Main, self).__init__(parent) # 信息。 self.result = {'uid': 0} # 歌单歌曲id。 self.playurl = {} # 搜索歌曲id。 self.ids = {} # 本地音乐地址。 self.local_url = {} # 歌曲图片。 self.pictures = {} # 歌曲列表id们。 self.playids = {} self.setObjectName('Main') self.setWindowFlags(Qt.FramelessWindowHint) self.setWindowTitle('NetEase') self.setWindowIcon(QIcon('icons/format.ico')) # 功能。 self.function = api.WebApi() # 主页及其他功能。 self.index = Index(self) self.current_list = SongsWindow(self) # ------- # 待改进。 self.resize(1000, 650) # 按钮start. self.btn_exit = QPushButton(self) self.btn_min = QPushButton(self) self.btn_max = QPushButton(self) self.btn_login = QPushButton("Unlogin", self) self.btn_search = QPushButton(self) self.find_music = QPushButton(self) self.locale_music = QPushButton(self) self.select_path = QPushButton(self) self.play = QPushButton(self) self.stop = QPushButton(self) self.nextSong = QPushButton(self) self.beforeSong = QPushButton(self) self.pause = QPushButton(self) self.btn_list = QPushButton(self) self.add_all_song = QPushButton(self) self.single = QPushButton(self) self.cycle = QPushButton(self) self.loop_flags = True # 按钮end. # ------- # 标签start. self.lbe_pic = QLabel(self) self.header_hr = QLabel(self) self.header_icon = QLabel(self) self.header_text = QLabel(self) self.spacing = QLabel(self) self.spacing2 = QLabel(self) self.spacing3 = QFrame() self.spacing4 = QFrame() self.songs_list = QLabel(self) self.song_pic = QLabel(self) self.time1 = QLabel(self) self.time2 = QLabel(self) self.song_name = QLabel(self) # 歌单内的信息。 self.detail_pic = QLabel(self) self.detail_pic.hide() self.detail_author = QLabel(self) self.detail_author.hide() self.detail_tag = QLabel(self) self.detail_tag.hide() self.detail_name = QLabel(self) self.detail_name.hide() self.detail_description = QLabel(self) self.detail_description.hide() # 标签end. # ------- # 输入框start. self.search_line = QLineEdit(self) # 输入框end. # ------- # 列表框start. self.playlist = PlayList(self) # 列表框end. # ------- # 表格start. self.table = QTableWidget(self) self.table.setObjectName("tablelist") # 表格连接信号. self.table.itemDoubleClicked.connect(self.add_song) self.table.itemDoubleClicked.connect(self.play_song) self.table.hide() # 表格end. # ------- # 滚动条start。 self.slider = QSlider(self) # 滚动条end. # ------- # 播放功能。 self.player = QMediaPlayer() # ------- # 布局与属性设置。 self.mainLayout = QGridLayout() self.topLayout = QHBoxLayout() self.leftLayout = QVBoxLayout() self.centerLayout = QHBoxLayout() self.rightLayout = QVBoxLayout() self.rightLayout1 = QHBoxLayout() self.rightLayout2 = QVBoxLayout() self.rightLayout21 = QHBoxLayout() self.bottomLayout = QHBoxLayout() self.bottomLayout1 = QVBoxLayout() self.playLayout = QHBoxLayout() self.set_buttons() self.set_labels() self.set_lines() self.set_sliders() self.set_medias() # ------- # 其他功能。 self.load_login() self.manager = QNetworkAccessManager() self.setLayout(self.set_layouts()) # 登陆部分start. def lwindow(self): """ 登陆框。 """ login = LoginWindow(self) login.exec_() def load_login(self): """ 查看是否已经登陆。 """ os.chdir('.' + '/data' + '/cookies') filedir = os.listdir('.') if filedir: try: with open(filedir[0], 'r') as f: content = f.readlines() self.result['uid'] = content[1][:-1] # 读入当前用户uid. self.btn_login.setText(content[0][:-1]) # 加载昵称。 self.btn_login.disconnect() self.btn_login.clicked.connect(self.quit_login) # 改变登陆按钮连接到退出功能。 with open(filedir[-1], 'rb') as fi: p3 = QPixmap() p3.loadFromData(QByteArray(fi.read())) self.lbe_pic.setStyleSheet("border: 0px;") # 发现圆角只是边框,图片并不变化。 self.lbe_pic.setPixmap(p3.scaled(40, 40)) # 加载头像。 self.btn_login.setToolTip("登出") except: pass else: pass os.chdir('..') os.chdir('..') try: self.playlist.set_list() except: pass def quit_login(self): """ 退出登陆。 """ self.set_labels() self.lbe_pic.setStyleSheet("") self.btn_login.setText("Unlogin") self.btn_login.disconnect() self.btn_login.clicked.connect(self.lwindow) self.playlist.disconnect() self.playlist.clear() shutil.rmtree('data/cookies') os.makedirs('.' + '/data' + '/cookies') # 登陆部分end. # 内置组件部分start. def set_buttons(self): """ 全部的按钮组件。 """ # 退出。 self.btn_exit.setObjectName('exit') self.btn_exit.setText('×') self.btn_exit.clicked.connect(self.close) self.btn_exit.setToolTip('退出') # 最小化。 self.btn_min.setObjectName('mini') self.btn_min.setText('-') self.btn_min.clicked.connect(self.showMinimized) self.btn_min.setToolTip('最小化') # 最大化。 self.btn_max.setObjectName('maxi') self.btn_max.setText('□') self.btn_max.setToolTip('^_^此功能已上火星') # 登陆。 self.btn_login.setObjectName('login') self.btn_login.clicked.connect(self.lwindow) self.btn_login.setToolTip('登陆') # 搜索。 self.btn_search.setObjectName('searchBtn') self.btn_search.resize(48, 48) self.btn_search.clicked.connect(self.song_search) # 发现音乐。 self.find_music.setObjectName('find') self.find_music.setIcon(QIcon('icons/music.png')) self.find_music.setText("发现音乐") self.find_music.clicked.connect(self.show_index) # 本地音乐。 self.locale_music.setObjectName('locale') self.locale_music.setIcon(QIcon('icons/music.png')) self.locale_music.setText("本地音乐") self.locale_music.clicked.connect(self.looking_music) self.select_path.setObjectName('selection') self.select_path.clicked.connect(self.set_path) self.select_path.setText("选择目录") self.select_path.hide() # 播放页。 self.play.setObjectName('play') self.play.setToolTip("播放歌曲") self.play.clicked.connect(self.play_song) self.stop.setObjectName('stop') self.stop.setToolTip("停止播放") self.stop.clicked.connect(self.stop_song) self.nextSong.setObjectName('next') self.nextSong.setToolTip("下一首歌曲") self.nextSong.clicked.connect(self.next_song) self.beforeSong.setObjectName('before') self.beforeSong.setToolTip("上一首歌曲") self.beforeSong.clicked.connect(self.before_song) self.pause.setObjectName("pause") self.pause.setToolTip("暂停播放") self.pause.hide() self.pause.clicked.connect(self.pause_song) self.single.setObjectName('single') self.single.setToolTip('单曲循环') self.single.clicked.connect(self.set_modles) self.single.hide() self.cycle.setObjectName('cycle') self.cycle.setToolTip('循环播放') self.cycle.clicked.connect(self.set_modles) # 歌曲列表。 self.btn_list.setObjectName('songslist') self.btn_list.clicked.connect(self.songs_lists) # 歌单内功能。 self.add_all_song.setObjectName("addbutton") self.add_all_song.setText("播放全部") self.add_all_song.clicked.connect(self.add_all) self.add_all_song.hide() def set_labels(self): """ 全部的标签组件。 """ p = QPixmap() p.load('icons/unlogin.png') p2 = QPixmap() p2.load('icons/format_2.png') # 头部装饰start。 self.lbe_pic.setObjectName("headpic") self.lbe_pic.setPixmap(p.scaled(40, 40)) self.header_hr.setObjectName('Headerhr') self.header_hr.setText("推荐") self.header_icon.setObjectName('HIcon') self.header_icon.setPixmap(p2.scaled(50, 50)) self.header_text.setObjectName('HText') self.header_text.setText(" Music") # 头部装饰end。 # 头部竖线装饰start。 self.spacing.setObjectName('spacing1') self.spacing.resize(50, 50) self.spacing2.setObjectName('spacing2') self.spacing2.resize(50, 50) # 头部竖线装饰end。 self.songs_list.setObjectName("songlist") self.songs_list.setText("我的音乐") # 歌单标签设置start。 self.detail_pic.setObjectName("pic") self.detail_author.setObjectName("author") self.detail_tag.setObjectName("tag") self.detail_name.setObjectName("name") self.detail_description.setObjectName("description") # 歌单标签设置end。 # 歌曲图片。 self.song_pic.setObjectName("songpic") p3 = QPixmap() p3.load('icons/nosong.png') self.song_pic.setPixmap(p3) # 时间显示组件。 self.time1.setObjectName("time1") self.time1.setText('00:00') self.time1.setAlignment(Qt.AlignCenter | Qt.AlignRight | Qt.AlignBottom) self.time2.setObjectName("time2") self.time2.setText('00:00') self.time2.setAlignment(Qt.AlignBottom) # 间隔装饰。 self.spacing3.setFrameShape(QFrame.VLine) self.spacing3.setFrameShadow(QFrame.Plain) self.spacing3.setLineWidth(2) self.spacing4.setFrameShape(QFrame.HLine) self.spacing3.setFrameShadow(QFrame.Plain) self.spacing3.setLineWidth(2) # 歌曲名字。 self.song_name.setObjectName("songname") self.song_name.setAlignment(Qt.AlignCenter) self.song_name.setText("~~~还没有歌曲呦~~~") def set_lines(self): """ 输入框。 """ self.search_line.setObjectName('SearchLine') self.search_line.setPlaceholderText('搜索音乐。') def set_sliders(self): """ 滚动组件。 """ self.slider.setObjectName("slider") self.slider.setOrientation(Qt.Horizontal) self.slider.sliderMoved.connect(self.slider_media) self.slider.sliderReleased.connect(self.slider_setdone) # 内置组件备份end. # 歌曲部分start. # 框架,播放器及功能的处理。 def set_tables(self): """ 表格呈现歌单详细信息。 """ self.table.setColumnCount(6) self.table.setHorizontalHeaderLabels([' ', '操作', '音乐', '歌手', '专辑', '时长']) self.table.setEditTriggers(QAbstractItemView.NoEditTriggers) # 设置列宽。 self.table.setColumnWidth(0, 40) self.table.setColumnWidth(1, 40) self.table.setColumnWidth(2, 360) self.table.setColumnWidth(3, 140) self.table.setColumnWidth(4, 140) self.table.setColumnWidth(5, 60) # 设置充满表宽。 self.table.horizontalHeader().setStretchLastSection(True) # 设置表头亮度。 self.table.horizontalHeader().setHighlightSections(False) # 设置每次选择为一行。 self.table.setSelectionBehavior(QAbstractItemView.SelectRows) # 设置垂直表头不显示。 self.table.verticalHeader().setVisible(False) def set_medias(self): """ 设置播放器。 """ self.player.setVolume(100) self.player.stateChanged.connect(self.loop) self.player.positionChanged.connect(self.set_time) def song_search(self): """ 搜索功能。 name: 歌曲名称。 id: 歌曲id。 artists: [0][1]['name']歌曲作者可能不止一人,['img1v1Url']作者头像。 album: ['name']专辑名称。 """ # 暂时只做一页。翻页属后续功能。 text = self.search_line.text() if text: self.set_tables() self.hide_index() details = self.function.search(text) try: # 搜到没有的情况。 songs = details['songs'] except KeyError: self.table.hide() self.detail_description.setText('〖很抱歉,木有此歌曲〗') return songcount = details['songCount'] if songcount > 100: count = 100 else: count = songcount self.table.setRowCount(count) for i in range(count): self.ids[str(i)] = songs[i]['id'] self.table.setItem(i, 0, QTableWidgetItem(str(i))) self.table.setItem(i, 1, QTableWidgetItem(QIcon('icons/playlist.png'), '')) self.table.setItem(i, 2, QTableWidgetItem(songs[i]['name'])) people = ','.join([c['name'] for c in songs[i]['artists']]) self.table.setItem(i, 3, QTableWidgetItem(people)) self.table.setItem(i, 4, QTableWidgetItem(songs[i]['album']['name'])) minuties = songs[i]['duration'] // 60000 seconds = songs[i]['duration'] // 1000 % 60 time = QTime(0, minuties, seconds) self.table.setItem(i, 5, QTableWidgetItem(time.toString("mm:ss"))) else: return # 加载图片。 pic = QPixmap() pic.load('icons/search2.jpg') self.detail_pic.setPixmap(pic.scaled(200, 200)) self.detail_name.setText('遨游在音乐的天空。') self.detail_author.setText("It's my sky!") self.detail_tag.setText('『Music, music』') self.detail_description.setText('〖Search Result〗') def show_playlist(self, name): """ 显示歌单详细信息。 trackCount: 总数。 name: 歌单名称。 tags: 歌单标签。 coverImgUrl: 歌单图片。 creator: ['nickname'] 创建者名字。 description: 歌单简介。 tracks: 歌曲总列表[] ,['bMusic']['id']歌曲id,['name']歌曲名称 , ['mp3Url']歌曲地址 , ['artists'][0]['name']歌曲作者,['id']作者id , ['album']['name']专辑名称,['blurPicUrl']图片。 """ self.set_tables() self.hide_index() details = self.function.details_playlist(self.result[name.replace('\n', '')]) self.table.setRowCount(details['trackCount']) # 加载在表格里。 for i in range(len(details['tracks'])): if not details['tracks'][i]['bMusic']['name']: self.playurl[str(i)] = details['tracks'][i]['id'] self.pictures[str(i)] = details['tracks'][i]['album']['blurPicUrl'] else: self.playurl[details['tracks'][i]['bMusic']['name']] = details['tracks'][i]['id'] self.pictures[details['tracks'][i]['bMusic']['name']] = details['tracks'][i]['album']['blurPicUrl'] # 设置序号。 self.table.setItem(i, 0, QTableWidgetItem(str(i))) self.table.setItem(i, 1, QTableWidgetItem(QIcon('icons/playlist.png'), '')) if not details['tracks'][i]['bMusic']['name']: self.table.setItem(i, 2, QTableWidgetItem(str(i))) else: self.table.setItem(i, 2, QTableWidgetItem(details['tracks'][i]['bMusic']['name'])) people = ','.join([t['name'] for t in details['tracks'][i]['artists']]) self.table.setItem(i, 3, QTableWidgetItem(people)) self.table.setItem(i, 4, QTableWidgetItem(details['tracks'][i]['album']['name'])) minuties = details['tracks'][i]['bMusic']['playTime'] // 60000 seconds = details['tracks'][i]['bMusic']['playTime'] // 1000 % 60 time = QTime(0, minuties, seconds) self.table.setItem(i, 5, QTableWidgetItem(time.toString("mm:ss"))) # 加载歌单图片。 self.manager.clearAccessCache() pic = self.manager.get(QNetworkRequest(QUrl(details['coverImgUrl']))) self.manager.finished.connect(lambda: load_pic(pic)) def load_pic(picture): p4 = QPixmap() p4.loadFromData(picture.readAll()) self.detail_pic.setPixmap(p4.scaled(200, 200)) # 加载歌单名称,创建者,标签,简介。 self.detail_name.setText('::======>>歌单: ' + details['name']) self.detail_author.setText('Creator: ' + details['creator']['nickname']) self.detail_tag.setText('『' + str(details['tags'])[1:-1] + '』') try: self.detail_description.setText('〖' + details['description'] + '〗') self.detail_description.setWordWrap(True) except TypeError: self.detail_description.setText('〖〗') # 歌曲组件start。 def set_song(self, name, author): """ 设置歌曲链接连接。 """ try: self.manager.disconnect() except TypeError: pass self.manager.clearAccessCache() try: self.player.setMedia(QMediaContent(QUrl(self.function.details_search(self.playids[name][author])))) data = self.manager.get(QNetworkRequest(QUrl(self.pictures[name]))) self.manager.finished.connect(lambda: self.load(data)) except KeyError: self.player.setMedia(QMediaContent(QUrl.fromLocalFile(self.playids[name][author]))) def add_song(self): """ 将歌曲加入到播放列表。 """ name = self.table.item(self.table.currentRow(), 2).text() author = self.table.item(self.table.currentRow(), 3).text() times = self.table.item(self.table.currentRow(), 5).text() content = author + ' - ' + name + ' - ' + times for i in range(self.current_list.count()): if self.current_list.item(i).text() == content: if self.current_list.currentItem().text() == content: break else: self.current_list.setCurrentRow(i) self.set_song(name, author) break else: self.current_list.addItem(content) self.current_list.setCurrentRow(self.current_list.count()-1) try: self.playids[name] except KeyError: self.playids[name] = {} try: self.playids[name][author] = self.playurl[name] except KeyError: self.playids[name][author] = self.ids[str(self.table.currentRow())] self.set_song(name, author) # 将列表保存到文件夹下。 with open('data/music/' + content.replace(':', '.'), 'w') as f: try: f.write(self.pictures[name]) except KeyError: pass def add_all(self): """ 将表格中所有的歌曲添加到播放列表。 """ for i in reversed(range(self.table.rowCount())): name = self.table.item(i, 2).text() author = self.table.item(i, 3).text() times = self.table.item(i, 5).text() content = name + ' - ' + author + ' - ' + times temp = [self.current_list.item(j).text() for j in range(self.current_list.count())] if content in temp: pass else: self.current_list.addItem(content) self.playids[name] = {} try: self.playids[name][author] = self.playurl[name] except KeyError: self.playids[name][author] = self.ids[str(self.table.currentRow())] with open('data/music/' + content.replace(':', '.'), 'w') as f: try: f.write(self.pictures[name]) except KeyError: pass self.set_song(name, author) self.play_song() def play_song(self): """ 播放组件。 """ # BUG: 用isAudio判断是否为有效音频是特么的双击居然显示无效。 try: self.song_name.setText(self.current_list.currentItem().text().split(' - ')[1]) self.time2.setText(self.current_list.currentItem().text().split(' - ')[2]) self.player.play() self.play.hide() self.pause.show() except AttributeError: return def pause_song(self): """ 暂停组件。 """ self.player.pause() self.pause.hide() self.play.show() def stop_song(self): """ 停止组件。 """ self.player.stop() self.pause.hide() self.play.show() def next_song(self): """ 下一首,若到头了则播放当前。 """ try: self.manager.disconnect() except TypeError: pass self.manager.clearAccessCache() try: content = self.current_list.item(self.current_list.currentRow()+1).text().split(' - ') self.song_name.setText(content[1]) self.time2.setText(content[2]) self.player.setMedia(QMediaContent(QUrl(self.function.details_search(self.playids[content[1]][content[0]])))) data = self.manager.get(QNetworkRequest(QUrl(self.pictures[content[1]]))) self.manager.finished.connect(lambda: self.load(data)) self.current_list.setCurrentRow(self.current_list.currentRow()+1) self.player.play() except AttributeError: self.player.play() def before_song(self): """ 前一首,若到头则播放当前。 """ try: self.manager.disconnect() except TypeError: pass self.manager.clearAccessCache() try: content = self.current_list.item(self.current_list.currentRow()-1).text().split(' - ') self.song_name.setText(content[1]) self.time2.setText(content[2]) self.player.setMedia(QMediaContent(QUrl(self.function.details_search(self.playids[content[1]][content[0]])))) data = self.manager.get(QNetworkRequest(QUrl(self.pictures[content[1]]))) self.manager.finished.connect(lambda: self.load(data)) self.current_list.setCurrentRow(self.current_list.currentRow()-1) self.player.play() except AttributeError: self.player.play() # 本地音乐查找start. def looking_music(self): """本地音乐查找组件。""" p = QPixmap() p.load('icons/local.jpg') self.detail_pic.setPixmap(p.scaled(200, 200)) self.detail_name.setText("本地音乐") self.detail_author.setText("You, You, You") self.detail_tag.setText("Your Collection Music") self.hide_index() self.select_path.show() self.set_tables() self.locale_show_on_table(os.getcwd() + r"\myMusic") def set_path(self): file_path = QFileDialog.getExistingDirectory(self, 'Select Folder') self.locale_show_on_table(file_path) def locale_show_on_table(self, path): songs_list = [i for i in os.listdir(path) if i[-3:] == 'mp3'] print(songs_list) self.table.setRowCount(len(songs_list)) for i in range(len(songs_list)): temp = songs_list[i][:-4] temp2 = temp.split(' - ') self.table.setItem(i, 0, QTableWidgetItem(str(i))) self.table.setItem(i, 1, QTableWidgetItem(QIcon('icons/playlist.png'), '')) try: self.table.setItem(i, 2, QTableWidgetItem(temp2[1])) self.table.setItem(i, 3, QTableWidgetItem(temp2[0])) except IndexError: self.table.setItem(i, 2, QTableWidgetItem(temp)) self.table.setItem(i, 3, QTableWidgetItem("暂时无法获取")) self.table.setItem(i, 4, QTableWidgetItem("暂时无法获取")) self.table.setItem(i, 5, QTableWidgetItem("暂时无法获取")) self.playids[temp] = {} self.playids[temp]["暂时无法获取"] = path + '\\' + songs_list[i] continue self.table.setItem(i, 4, QTableWidgetItem("暂时无法获取")) self.table.setItem(i, 5, QTableWidgetItem("暂时无法获取")) self.playids[temp2[1]] = {} self.playids[temp2[1]][temp2[0]] = path + '\\' + songs_list[i] # 本地音乐查找end. # 歌曲组件end. # 歌曲图片,时间和滚动条的设置。 def load(self, data): """用于加载选中歌曲的图片。""" data = data.readAll() p = QPixmap() if data: p.loadFromData(data) self.song_pic.setPixmap(p.scaled(64, 64)) else: p.load('icons/nosong.png') self.song_pic.setPixmap(p.scaled(64, 64)) def set_time(self): """ 设置当前时间。 """ times = self.player.position() / 1000 minutes = times // 60 seconds = times % 60 time = QTime(0, minutes, seconds) self.time1.setText(time.toString("mm:ss")) try: alltime = float(self.current_list.item(\ self.current_list.currentRow()).text().split(' - ')[2].replace(':', '.')) except (AttributeError, ValueError): return curtime = float(time.toString('mm.ss')) self.slider.setValue((curtime / alltime) * 100) def slider_media(self): """ 拖动滚动条时时间的改变。基于时间的变化,若无法获取到时间是不变的,且会报ValueError的错误。当然可以随便写个2:00冒充。- -。 """ try: self.player.positionChanged.disconnect() except TypeError: pass content = self.current_list.item(self.current_list.currentRow()).text().split(' - ') alltime = float(content[2].replace(':', '.')) trans_alltime = int(alltime) * 60 + (alltime - int(alltime)) * 100 currentTime = trans_alltime * self.slider.value() minuties = currentTime / 100 // 60 seconds = currentTime / 100 % 60 time = QTime(0, minuties, seconds) self.time1.setText(time.toString("mm:ss")) def slider_setdone(self): """ 鼠标放开后播放位置。待改进。 """ self.player.positionChanged.connect(self.set_time) content = self.current_list.item(self.current_list.currentRow()).text().split(' - ') alltime = float(content[2].replace(':', '.')) trans_alltime = int(alltime) * 60 + (alltime - int(alltime)) * 100 currentTime = trans_alltime * self.slider.value() self.player.setPosition(currentTime * 10) # 设置歌曲播放模式。 def set_modles(self): """ 切换图标及将循环标志变false。 """ if self.loop_flags: self.cycle.hide() self.single.show() self.loop_flags = False else: self.single.hide() self.cycle.show() self.loop_flags = True def loop(self): """ 设置为循环播放。默认。 """ if self.player.position() > 0 and self.player.state() == 0 and self.loop_flags: try: self.manager.disconnect() except TypeError: pass self.manager.clearAccessCache() content = self.current_list.item(self.current_list.currentRow()+1).text().split(' - ') self.current_list.setCurrentRow(self.current_list.currentRow()+1) try: self.player.setMedia(\ QMediaContent(QUrl(self.function.details_search(self.playids[content[1]][content[0]])))) data = self.manager.get(QNetworkRequest(QUrl(self.pictures[content[1]]))) self.manager.finished.connect(lambda: self.load(data)) except KeyError: self.player.setMedia(QMediaContent(QUrl.fromLocalFile(self.playids[content[1]][content[0]]))) self.play_song() elif self.player.state() == 0: self.solo() def solo(self): """ 设置为单曲。 """ self.player.setPosition(0) self.play_song() # 歌曲部分end. # ------- # 切换页面start。 def songs_lists(self): """ 歌曲列表。 """ if self.current_list.flag: self.current_list.show() self.current_list.flag = False else: self.current_list.hide() self.current_list.flag = True def hide_index(self): """ 隐藏主页, 显示歌单详细信息。 """ self.centerLayout.setStretch(0, 160) self.centerLayout.setStretch(1, 1) self.centerLayout.setStretch(2, 850) self.centerLayout.setStretch(3, 0) self.centerLayout.setStretch(4, 0) self.index.hide() self.select_path.hide() self.current_list.hide() self.detail_pic.show() self.detail_name.show() self.detail_author.show() self.add_all_song.show() self.detail_tag.show() self.detail_description.show() self.table.show() def show_index(self): """ 显示主页。 """ self.centerLayout.setStretch(0, 160) self.centerLayout.setStretch(1, 1) self.centerLayout.setStretch(2, 0) self.centerLayout.setStretch(3, 850) self.centerLayout.setStretch(4, 0) self.current_list.hide() self.detail_pic.hide() self.detail_name.hide() self.select_path.hide() self.detail_author.hide() self.add_all_song.hide() self.detail_tag.hide() self.detail_description.hide() self.table.hide() self.index.show() # 切换页面end. # 设置布局。 def set_layouts(self): """ 布局。 """ # 头布局start. self.topLayout.setObjectName('Headerhbox') self.topLayout.addWidget(self.header_icon) self.topLayout.addWidget(self.header_text) self.topLayout.addWidget(self.spacing2) self.topLayout.addWidget(self.search_line) self.topLayout.addWidget(self.btn_search) self.topLayout.addStretch(1) self.topLayout.addWidget(self.lbe_pic) self.topLayout.addWidget(self.btn_login) self.topLayout.addWidget(self.spacing) self.topLayout.addWidget(self.btn_min) self.topLayout.addWidget(self.btn_max) self.topLayout.addWidget(self.btn_exit) self.topLayout.setSpacing(7) # ------- self.mainLayout.addLayout(self.topLayout, 0, 0, Qt.AlignTop) self.mainLayout.addWidget(self.header_hr, 1, 0, Qt.AlignTop) # 头布局end. # -------- # 中心布局start. # 左部分start. self.leftLayout.addWidget(self.find_music) self.leftLayout.addWidget(self.locale_music) self.leftLayout.addWidget(self.songs_list) self.leftLayout.addWidget(self.playlist) self.leftLayout.setSpacing(10) # 左部分end。 # ------- # 右部分start. self.rightLayout.addLayout(self.rightLayout1) self.rightLayout1.addWidget(self.detail_pic) self.rightLayout1.addLayout(self.rightLayout2) self.rightLayout1.setStretch(0, 1) self.rightLayout1.setStretch(1, 5) self.rightLayout21.addWidget(self.detail_name) self.rightLayout21.addWidget(self.select_path) self.rightLayout21.addStretch(1) self.rightLayout2.addLayout(self.rightLayout21) self.rightLayout2.addWidget(self.detail_author) self.playLayout.addWidget(self.add_all_song) self.playLayout.addStretch(1) self.rightLayout2.addLayout(self.playLayout) self.rightLayout2.addWidget(self.detail_tag) self.rightLayout2.addWidget(self.detail_description) self.rightLayout.addWidget(self.table) self.rightLayout.setStretch(0, 1) self.rightLayout.setStretch(1, 2) # 右部分end. # ------- self.centerLayout.addLayout(self.leftLayout) self.centerLayout.addWidget(self.spacing3) self.centerLayout.addLayout(self.rightLayout) self.centerLayout.addWidget(self.index) self.centerLayout.addWidget(self.current_list) self.centerLayout.setStretch(0, 180) self.centerLayout.setStretch(1, 1) self.centerLayout.setStretch(2, 0) self.centerLayout.setStretch(3, 830) self.centerLayout.setStretch(4, 0) self.mainLayout.addLayout(self.centerLayout, 2, 0, Qt.AlignTop | Qt.AlignLeft) # 中心布局end. # ------- # 下部分start. self.bottomLayout.addWidget(self.stop) self.bottomLayout.addWidget(self.beforeSong) self.bottomLayout.addWidget(self.play) self.bottomLayout.addWidget(self.pause) self.bottomLayout.addWidget(self.nextSong) self.bottomLayout.addWidget(self.song_pic) self.bottomLayout.addWidget(self.time1) self.bottomLayout1.addWidget(self.song_name) self.bottomLayout1.addWidget(self.slider) self.bottomLayout.addLayout(self.bottomLayout1) self.bottomLayout.addWidget(self.time2) self.bottomLayout.addWidget(self.cycle) self.bottomLayout.addWidget(self.single) self.bottomLayout.addWidget(self.btn_list) self.bottomLayout.setStretch(6, 1) self.bottomLayout.setStretch(7, 6) self.bottomLayout.setStretch(8, 1) self.mainLayout.addWidget(self.spacing4, 3, 0, Qt.AlignTop) self.mainLayout.addLayout(self.bottomLayout, 3, 0, Qt.AlignBottom) # self.mainLayout.addWidget(self.current_list, 2, 0, Qt.AlignBottom | Qt.AlignRight) # 下部分end. self.mainLayout.setRowStretch(1, 1) self.mainLayout.setRowStretch(2, 20) self.mainLayout.setRowStretch(3, 3) return self.mainLayout """重写鼠标事件,实现窗口拖动。""" def mousePressEvent(self, event): if event.buttons() == Qt.LeftButton: self.m_drag = True self.m_DragPosition = event.globalPos()-self.pos() event.accept() def mouseMoveEvent(self, event): try: if event.buttons() and Qt.LeftButton: self.move(event.globalPos()-self.m_DragPosition) event.accept() except AttributeError: pass def mouseReleaseEvent(self, event): self.m_drag = False """按键绑定。。""" def keyPressEvent(self, event): if event.key() == Qt.Key_Enter or event.key() == Qt.Key_Enter-1: self.song_search() """退出窗口时做的一些事。""" def closeEvent(self, event): # 退出时保存歌曲列表缓存。 try: with open('data/music/load/playids.pkl', 'wb') as f: pickle.dump(self.playids, f) except FileNotFoundError: pass """界面开始前的一些事。""" def showEvent(self, event): # 查看是否有歌曲缓存。 try: with open('data/music/load/playids.pkl', 'rb') as r: self.playids = pickle.load(r) # 没有就算了。 except FileNotFoundError: pass # 没有也不会报错。 for i in os.listdir('.' + '/data/music/'): if os.path.isfile('.' + '/data/music/' + i): self.current_list.addItem(i.replace('.', ':')) with open('.' + '/data/music/' + i, 'r') as f: self.pictures[i.split(' - ')[1]] = f.read() # 有的话设置为0,防止其他功能报错。 self.current_list.setCurrentRow(0)
class MainWindow(QMainWindow, Ui_MainWindow): settings = QSettings('Rafał Jagoda', 'Peer 2 cinema') settings.setFallbacksEnabled(False) version = '1.0' def __init__( self, parent=None ): QMainWindow.__init__(self, parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.media_player = None self.setWindowTitle('name of the software - ' + self.version) signal.signal(signal.SIGINT, signal.SIG_DFL) self.show() self.timer = QTimer(self) self.current_category = None def play(self, movie: Movie): self.app.play(movie) self.media_player.play() self.playButton.setEnabled(True) def connect_app(self, app: P2CDaemon): self.app = app self._set_categories() self._connect_signals() def change_category(self, item): index = self.menuTree.indexOfTopLevelItem(item) category = self.app.get_categories()[index] self.current_category = category self.itemList.clear() threading.Thread(target=self._set_torrents).start() def activate_torrent(self, item): self.update_status() def update_status(self): index = self.itemList.currentIndex().row() if index != -1: data= {} torrent_ui = self.current_category.get_torrents()[index] torrent = self.app.get_torrent(torrent_ui) if torrent and torrent.has_torrent_info(): movie = torrent.get_downloading_movie() if movie: data['movie'] = movie.name if self.media_player: self.positionSlider.setBackgroundValue(movie.progress * self.media_player.duration()) data['movie progress'] = "{0:.2f}%".format(movie.progress * 100) data['can_play'] = movie.can_play() data.update(torrent.get_status()) # TODO: buggy due to setting priority to 0 if data['state'] == 'downloading': del data['progress'] else: data['progress'] = "{0:.2f}%".format(data['progress'] * 100) data['download_rate'] = "{0:.2f} kb/s".format(data['download_rate']/1000) else: data['status'] = "Getting metadata" text = "\n".join(["{}: {}".format(k,data[k]) for k in data]) else: text="select item" self.statusArea.setText(text) def run_torrent(self, item): index = self.itemList.currentIndex() torrent_ui = self.current_category.get_torrents()[index.row()] torrent = self.app.get_torrent(torrent_ui) if(torrent.has_torrent_info()): movies = torrent.get_movies() # DEVELOPMENT movie = max(movies, key=lambda x:x.size) torrent.download_file(movie.path) if(movie.can_play()): self._set_media(movie) self.play(movie) else: self.app.buffer(movie) def _set_categories(self): for category in self.app.get_categories(): item = QTreeWidgetItem(self.menuTree) item.setText(0, category.label) def _set_torrents(self): category = self.current_category items = map(lambda x: x.label, category.get_torrents(limit=20)) # after long call if(self.current_category == category): self.itemList.addItems(list(items)) def toggle_player(self): if self.media_player.state() == QMediaPlayer.PlayingState: self.media_player.pause() else: self.media_player.play() def set_player_position(self, position): self.media_player.setPosition(position) def media_state_changed(self, state): if state == QMediaPlayer.PlayingState: self.playButton.setIcon(self.videoArea.style().standardIcon(QStyle.SP_MediaPause)) else: self.playButton.setIcon(self.videoArea.style().standardIcon(QStyle.SP_MediaPlay)) def position_changed(self, position): self.positionSlider.setValue(position) def duration_changed(self, duration): self.positionSlider.setRange(0, duration) def _connect_signals(self): self.menuTree.currentItemChanged.connect(self.change_category) self.itemList.currentItemChanged.connect(self.activate_torrent) self.itemList.itemDoubleClicked.connect(self.run_torrent) self.timer.timeout.connect(self.update_status) self.timer.start(500) def _connect_player_signals(self): self.playButton.clicked.connect(self.toggle_player) self.positionSlider.sliderMoved.connect(self.set_player_position) self.media_player.stateChanged.connect(self.media_state_changed) self.media_player.durationChanged.connect(self.duration_changed) self.media_player.positionChanged.connect(self.position_changed) def _set_media(self, movie: Movie): if self.media_player is None: self.media_player = QMediaPlayer(self.videoArea, QMediaPlayer.VideoSurface) self.media_player.setVideoOutput(self.videoArea.videoSurface()) self._connect_player_signals() file_name = movie.get_target_path() mimetype = mimetypes.guess_type(file_name)[0] logger.debug("Found mimetype: {}".format(mimetype)) media_res = QMediaResource(QUrl.fromLocalFile(file_name), mimetype) media = QMediaContent(media_res) self.media_player.setMedia(media)
class VideoPlayer(QWidget): def __init__(self, parent=None): super(VideoPlayer, self).__init__(parent) self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface) videoWidget = QVideoWidget() 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) self.errorLabel = QLabel() self.errorLabel.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum) controlLayout = QHBoxLayout() controlLayout.setContentsMargins(0, 0, 0, 0) controlLayout.addWidget(openButton) controlLayout.addWidget(self.playButton) controlLayout.addWidget(self.positionSlider) layout = QVBoxLayout() layout.addWidget(videoWidget) layout.addLayout(controlLayout) layout.addWidget(self.errorLabel) self.setLayout(layout) self.mediaPlayer.setVideoOutput(videoWidget) self.mediaPlayer.stateChanged.connect(self.mediaStateChanged) self.mediaPlayer.positionChanged.connect(self.positionChanged) self.mediaPlayer.durationChanged.connect(self.durationChanged) self.mediaPlayer.error.connect(self.handleError) def 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 handleError(self): self.playButton.setEnabled(False) self.errorLabel.setText("Error: " + self.mediaPlayer.errorString())
class EventAction(): def __init__(self): #self.parent = parent self.isLoop = 0 #0循环列表,1单曲循环 self.isRandom = 0 #0不随机,1随机 self.fileList = [] #曲目名称列表 self.randomList =[] #播放列表 self.soundID = 0 #当前歌曲ID self.playStat = False #当前播放状态 (0未播放,1播放) self.openPath = "F:/mp3/" #歌曲目录 self.isPreview = 0 #试用开关,0正常播放,1列表中的歌曲每首歌曲放10秒 self.currentVolume = 0.1#默认的起始音量 self.isInitPlay = 1 #是否是初始播放 #==>>打开目录 self.config=configparser.ConfigParser() self.config.read('config.ini') self.openDir() #打开目录<<== self.playObj = QMediaPlayer() self.currentImg = "" #当前图片 self.songText = {} #歌词 self.songTextKey=[] #歌词KEY #打开歌曲目录 def openDir(self): self.openPath = self.config.get('Save','musicPath') isMusicDir = os.path.isdir(self.openPath)#检查是否为目录 if isMusicDir: dirFile = os.listdir(self.openPath)#目录中的所有文件 #遍历有效音乐文件 i=0; for file in dirFile: fileName,fileType=os.path.splitext(file) if fileType==".mp3" or fileType==".wav": self.fileList.append(file) self.randomList.append(i) i+=1 if self.isRandom==1: self.shuffleMusic(1) #随机(打乱播放顺序) def shuffleMusic(self,isshuffle): if isshuffle: random.shuffle(self.randomList)#乱序 else: self.randomList.sort()#排序 #初始化播放 def initPlay(self): self.soundID = int(self.config.get('Save','soundID')) self.playStat = self.config.get('Save','playStat') self.pastTime = self.config.getint('Save','pastTime') self.currentVolume = self.config.getint('Save','volume') self.isRandom = self.config.getint('Save','isRandom') self.isLoop = self.config.getint('Save','isLoop') if self.soundID!="": self.play(self.soundID) if self.isRandom:#打乱列表 self.shuffleMusic(1) self.playObj.setVolume(self.currentVolume) #播放 def play(self,i): source = self.openPath + self.fileList[i] self.playObj.setMedia(QMediaContent(QUrl.fromLocalFile(source))) #解析文件中的ID3V2 self.currentImg = "" f = QFile(source) if f.open(QIODevice.ReadOnly): #读取标签 headData = f.read(10) data = headData[:0] if self.id3v2(headData):#检测是否有ID3 #标签的大小计算 tag = headData[6:10] tagSize = (tag[0]&0x7f)*0x200000+(tag[1]&0x7f)*0x4000+(tag[2]&0x7f)*0x80+(tag[3]&0x7f) data =f.read(tagSize) while len(data)>10: data = self.resolve(data) f.close() self.playObj.play() def testPlay(self): #ps =QMediaMetaData() #print("QMediaMetaData",ps) #print("metaData",self.playObj.metaData(QMediaMetaData.Title)) #print("position",self.playObj.position()) #print("playlist",self.playObj.playlist) #print("availability",self.playObj.availability()) #print("bufferStatus",self.playObj.bufferStatus()) #print("currentMedia",self.playObj.currentMedia()) #print("currentNetworkConfiguration",self.playObj.currentNetworkConfiguration()) #print("duration",self.playObj.duration()) #print("error",self.playObj.error()) #print("errorString",self.playObj.errorString()) #print("isAudioAvailable",self.playObj.isAudioAvailable()) #print("isMuted",self.playObj.isMuted()) #print("isSeekable",self.playObj.isSeekable()) #print("media",self.playObj.media()) #print("media:::::::A",self.playObj.media().canonicalResource().audioBitRate()) #print("media:::::::B",self.playObj.media().canonicalResource().audioCodec()) #print("media:::::::C",self.playObj.media().canonicalResource().channelCount()) #print("media:::::::D",self.playObj.media().canonicalResource().dataSize()) #print("media:::::::e",self.playObj.media().canonicalResource().isNull()) #print("media:::::::f",self.playObj.media().canonicalResource().language()) #print("media:::::::g",self.playObj.media().canonicalResource().mimeType()) #print("media:::::::h",self.playObj.media().canonicalResource().request()) #print("isVideoAvailable",self.playObj.isVideoAvailable()) #print("mediaStatus",self.playObj.mediaStatus()) #print("mediaStream",self.playObj.mediaStream()) #print("playbackRate",self.playObj.playbackRate()) #print("state",self.playObj.state()) #print("volume",self.playObj.volume()) # print("volume",self.playObj.filename) pass #换歌之前先停止,释放内存 def stopPlay(self): self.playObj.pause() #上一首 def prevPlay(self): self.stopPlay() if self.isRandom: key = self.searchID(self.soundID)-1 if key<0: key=0 self.soundID = self.randomList[key] else: self.soundID-=1 if self.soundID< 0: self.soundID = len(self.randomList)-1 self.play(self.soundID) #下一首 def nextPlay(self): self.stopPlay() if self.isRandom: key = self.searchID(self.soundID)+1 if key>(len(self.randomList)-1): key=len(self.randomList)-1 self.soundID = self.randomList[key] else: self.soundID+=1 if self.soundID > (len(self.randomList)-1): self.soundID = 0 #print("next:::",self.soundID) self.play(self.soundID) #快退 def rewindPlay(self): #print("<<") rewindTime = int(self.playObj.position()) - 10*1000 if rewindTime < 0: rewindTime = 0 self.playObj.setPosition(rewindTime) #快进 def forwardPlay(self): #print(">>") forwardTime = int(self.playObj.position()) + 10*1000 if forwardTime > int(self.playObj.duration()): forwardTime = int(self.playObj.duration()) self.playObj.setPosition(forwardTime) #播放/暂停 def playORpause(self): if self.playObj.state()==1: self.playObj.pause() else: self.playObj.play() #音量加 def raisevolPlay(self): self.playObj.setVolume(self.playObj.volume()+10) self.currentVolume = self.playObj.volume() #音量减 def lowervolPlay(self): self.playObj.setVolume(self.playObj.volume()-10) self.currentVolume = self.playObj.volume() #静音 def mutePlay(self): if self.playObj.isMuted(): self.playObj.setMuted(False) else: self.playObj.setMuted(True) #volume #跟据v找K def searchID(self,v): for index, item in enumerate(self.randomList): if item ==v: return index return 0 #解析文件中是否有id3v2 def id3v2(self,headData): if str(headData[:3],encoding=("utf-8")) != "ID3": return False return True #解析文件中的歌词与图片 def resolve(self,data): tagName = str(data[:4],encoding=("utf-8")) size = data[4:8] #sizeS = size[0]*0x1000000 + size[1]*0x10000 + size[2]*0x100 + size[3] sizeS=int.from_bytes(size, byteorder='big') flags = data[8:10] tagContent = data[10:sizeS+10] if tagName=="TEXT":#歌词 #print("歌词") condingType=int.from_bytes(tagContent[:1], byteorder='big') if condingType == 0:#0代表字符使用ISO-8859-1编码方式; try: content = str(tagContent[1:],encoding="gbk") except: content ="" elif condingType == 1:#1代表字符使用UTF-16编码方式; try: content = str(tagContent[1:],encoding="UTF-16") except: content ="" elif condingType == 2:#2代表字符使用 UTF-16BE编码方式; content ="" elif condingType == 3:#3代表字符使用UTF-8编码方式。 try: content = str(tagContent[1:],encoding="UTF-8") except: content ="" if content!="": temp={} self.songTextKey=[] contentSplit = content.splitlines() for k in range(len(contentSplit)): if contentSplit[k][1].isdigit(): xxx = contentSplit[k].split("]") tempKey = "%d" %(int(xxx[0][1:3])*60 +int(xxx[0][4:6]) ) temp[str(tempKey)] = xxx[1] self.songTextKey.append(tempKey) else: endKey = contentSplit[k].find("]",0) self.songTextKey.append(k) temp[str(k)] = contentSplit[k][1:endKey] self.songText = temp else: self.songText = {} elif tagName=="APIC":#图片 #print("图片") self.currentImg = tagContent[17:] return data[10+sizeS:]