New playback of another video file in PyQT5 using VLC - python

I am writing a script that, when launched, plays a video by its number. Then, after the end of playback, the script asks for the video number for the next playback, and so on. I use VLC python in PyQT5.
import sys
import time
import vlc
from PyQt5 import QtGui, QtWidgets
from PyQt5.QtCore import Qt
class Player(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(Player, self).__init__(parent)
self.setWindowTitle("Media Player")
# creating a basic vlc instance
self.instance = vlc.Instance(['--video-on-top'])
self.instance.log_unset()
self.media=None
self.mediaplayer = self.instance.media_player_new()
self.create_ui()
self.open_file()
def create_ui(self):
self.videoframe = QtWidgets.QFrame(
frameShape=QtWidgets.QFrame.Box, frameShadow=QtWidgets.QFrame.Raised)
if sys.platform.startswith("linux"): # for Linux using the X Server
self.mediaplayer.set_xwindow(self.videoframe.winId())
elif sys.platform == "win32": # for Windows
self.mediaplayer.set_hwnd(self.videoframe.winId())
elif sys.platform == "darwin": # for MacOS
self.mediaplayer.set_nsobject(self.videoframe.winId())
central_widget = QtWidgets.QWidget()
self.setCentralWidget(central_widget)
self.setWindowFlags(Qt.FramelessWindowHint)
lay = QtWidgets.QVBoxLayout(central_widget)
lay.addWidget(self.videoframe)
def play(self):
if self.mediaplayer.play() == -1:
self.open_file()
self.mediaplayer.play()
def open_file(self):
numberfile = input("Number file: ")
filename = (f"/home/Tadont/Video/{numberfile}.mp4")
self.media = self.instance.media_new(filename)
self.mediaplayer.set_media(self.media)
self.eventManager=self.mediaplayer.event_manager()
self.eventManager.event_attach(vlc.EventType.MediaPlayerEndReached, self.next_file)
self.play()
def next_file(self, event):
if event.type == vlc.EventType.MediaPlayerEndReached:
#self.mediaplayer.stop()
self.open_file()
def main():
app = QtWidgets.QApplication(sys.argv)
player = Player()
player.show()
player.move(1, 1)
player.resize(406, 86)
player.setObjectName("MainWindow")
player.setStyleSheet("#MainWindow{background-color:black}")
sys.exit(app.exec_())
if __name__ == "__main__":
main()
I have the first file to play, then I write the file number for the second playback, but the second file does not start. How to solve this problem?
I guess I don't have a new
self.media

Related

Fading effect with QAudioOutput and QMediaPlayer (PyQt6)

I'm working on a music player app, but i came across a problem which I don't know how to solve. I want audio to fade in in given interval (0.6 second for example) when audio is started or unpaused and also fade out in the same interval when it is paused. I tried doing it with QThread to keep my ui responsive while gradually lowering volume with for loop (iterating 10 times and every time lowering volume and sleeping for certaing time, 0.6 / 10 seconds). But it doesn't work, buttons are still unclickable and update only after fade in or fade out. If anyone managed to solve a problem like this please help, would greatly appreciate it! Here's simple code for playing audio in pyqt:
import sys
from PyQt6 import QtWidgets
from PyQt6.QtCore import QUrl
from PyQt6.QtMultimedia import QMediaPlayer, QAudioOutput
from PyQt6.QtWidgets import QWidget, QVBoxLayout, QPushButton, QStyle
class MainWindowUi(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self._setup_ui()
self.setWindowTitle('sound fading')
self.setGeometry(100, 100, 100, 100)
def _setup_ui(self):
self.central_widget = QWidget(self)
self.central_widget_layout = QVBoxLayout(self.central_widget)
self.setCentralWidget(self.central_widget)
self.player = AudioPlayer()
self.user_action = -1 # 0 - stopped, 1 - playing, 2 - paused
self.play_button = QPushButton()
self.play_button.clicked.connect(self.play_pause_button_clicked)
self.play_icon = self.style().standardIcon(QStyle.StandardPixmap.SP_MediaPlay)
self.pause_icon = self.style().standardIcon(QStyle.StandardPixmap.SP_MediaPause)
self.play_button.setIcon(self.play_icon)
self.central_widget_layout.addWidget(self.play_button)
def play(self):
print("Play")
self.play_button.setIcon(self.pause_icon)
self.user_action = 1
self.player.setSource(QUrl("Some audio file path goes here."))
self.player.play()
def pause(self):
print("Pause")
self.play_button.setIcon(self.play_icon)
self.user_action = 2
self.player.pause()
def unpause(self):
print("Unpause")
self.play_button.setIcon(self.pause_icon)
self.user_action = 1
self.player.play()
def play_pause_button_clicked(self):
if self.user_action <= 0:
self.play()
elif self.user_action == 1:
self.pause()
elif self.user_action == 2:
self.unpause()
class AudioPlayer(QMediaPlayer):
def __init__(self, parent=None):
super().__init__(parent)
self.audio_output = QAudioOutput()
self.setAudioOutput(self.audio_output)
self.audioOutput().setVolume(0.3)
self.current_volume = self.audio_output.volume()
def play(self):
super().play()
def pause(self):
super().pause()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
mainWindow = MainWindowUi()
mainWindow.show()
sys.exit(app.exec())
So I made it work with QPropertyAnimation! Still working on key values and easing curves but does is much, much closer to the result I want.
import sys
from PyQt6 import QtWidgets
from PyQt6.QtCore import QUrl, QPropertyAnimation, QEasingCurve
from PyQt6.QtMultimedia import QMediaPlayer, QAudioOutput
from PyQt6.QtWidgets import QWidget, QVBoxLayout, QPushButton, QStyle
from audio_player import AudioPlayer
class MainWindowUi(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self._setup_ui()
self.setWindowTitle('sound fading')
self.setGeometry(100, 100, 100, 100)
def _setup_ui(self):
self.central_widget = QWidget(self)
self.central_widget_layout = QVBoxLayout(self.central_widget)
self.setCentralWidget(self.central_widget)
self.player = AudioPlayer()
self.user_action = -1 # 0 - stopped, 1 - playing, 2 - paused
self.play_button = QPushButton()
self.play_button.clicked.connect(self.play_pause_button_clicked)
self.play_icon = self.style().standardIcon(QStyle.StandardPixmap.SP_MediaPlay)
self.pause_icon = self.style().standardIcon(QStyle.StandardPixmap.SP_MediaPause)
self.play_button.setIcon(self.play_icon)
self.central_widget_layout.addWidget(self.play_button)
def play(self):
print("Play")
self.play_button.setIcon(self.pause_icon)
self.user_action = 1
self.player.setSource(QUrl("some audio file path"))
self.player.play()
def pause(self):
print("Pause")
self.play_button.setIcon(self.play_icon)
self.user_action = 2
self.player.pause()
def unpause(self):
print("Unpause")
self.play_button.setIcon(self.pause_icon)
self.user_action = 1
self.player.play()
def play_pause_button_clicked(self):
if self.user_action <= 0:
self.play()
elif self.user_action == 1:
self.pause()
elif self.user_action == 2:
self.unpause()
class AudioPlayer(QMediaPlayer):
def __init__(self, parent=None):
super().__init__(parent)
self.audio_output = QAudioOutput()
self.audio_output.volumeChanged.connect(lambda: print(self.audio_output.volume()))
self.setAudioOutput(self.audio_output)
self.audioOutput().setVolume(.5)
self.current_volume = self.audio_output.volume()
self.fade_in_anim = QPropertyAnimation(self.audio_output, b"volume")
self.fade_in_anim.setDuration(1400)
self.fade_in_anim.setStartValue(0.01)
self.fade_in_anim.setEndValue(self.current_volume)
self.fade_in_anim.setEasingCurve(QEasingCurve.Type.Linear)
self.fade_in_anim.setKeyValueAt(0.01, 0.01)
self.fade_out_anim = QPropertyAnimation(self.audio_output, b"volume")
self.fade_out_anim.setDuration(600)
self.fade_out_anim.setStartValue(self.current_volume)
self.fade_out_anim.setEndValue(0)
self.fade_out_anim.setEasingCurve(QEasingCurve.Type.Linear)
self.fade_out_anim.setKeyValueAt(0.01, self.current_volume)
self.fade_out_anim.finished.connect(super().pause)
def play(self):
self.audio_output.setVolume(0.01)
self.fade_in_anim.setEndValue(self.current_volume)
super().play()
self.fade_in_anim.start()
def pause(self):
self.current_volume = self.audio_output.volume()
self.fade_out_anim.setStartValue(self.current_volume)
self.fade_out_anim.start()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
mainWindow = MainWindowUi()
mainWindow.show()
sys.exit(app.exec())

PyQt5 event filter occassionally not gaining focus when window is deactivated

I want to create a customizedwindow such that whenever window is deactivated.
The window becomes the 'active' window and regains the focus to the window
Below code is sort of working but randomly stops making the window 'active' after several window
deactivates, when this happens the app just blinks on the bottom of the toolbar or is just highlighted.
(Btw im using windows 7 if it matters)
from PyQt5.QtWidgets import QMainWindow, QApplication
from PyQt5 import QtCore
import sys
class myWindow(QMainWindow):
def __init__(self, parent=None):
super(myWindow, self).__init__(parent)
self.installEventFilter(self)
self.counter = 0
def eventFilter(self, obj, event):
if event.type() == QtCore.QEvent.WindowDeactivate:
self.counter += 1
print(self.counter)
self.raise_()
self.activateWindow()
return False
return False
if __name__ == '__main__':
app = QApplication(sys.argv)
win = myWindow()
win.show()
sys.exit(app.exec())
I found a better implementation using win32gui and win32com.client, I think it depends on which os you're using since the previous (while loop implementation) wasnt working with windows 10. Had this working for several pc's now
from PyQt5.QtWidgets import QMainWindow, QApplication
from PyQt5 import QtCore
import sys
import win32gui
import win32com.client
class myWindow(QMainWindow):
def __init__(self, parent=None):
super(myWindow, self).__init__(parent)
self.installEventFilter(self)
self.counter = 0
def eventFilter(self, obj, event):
if event.type() == QtCore.QEvent.WindowDeactivate:
if not self.isActiveWindow():
self.refocus_window()
return False
return False
def refocus_window():
try:
hwnd = win32gui.FindWindow(None, 'Repair')
win32gui.ShowWindow(hwnd, 9)
shell = win32com.client.Dispatch('WScript.Shell')
shell.SendKeys('%')
win32gui.SetForegroundWindow(hwnd)
except Exception as err:
raise err
if __name__ == '__main__':
app = QApplication(sys.argv)
win = myWindow()
win.show()
sys.exit(app.exec())

clear file selection when press on blank area in Qtreeview

Im using QFileSystemModel and QTreeView in my application(Pyqt5). I was looking for a way which I can clear file selection when press on the white blank area... to be more specific im need a way to know how to check whether the user press on the blank area in order to not choose at any file.
You have to detect the click with an event filter and then determine if a valid QModelIndex is associated, and in the case of the empty area it is not associated with a QModelIndex:
import os
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.model = QtWidgets.QFileSystemModel(self)
self.view = QtWidgets.QTreeView()
self.setCentralWidget(self.view)
self.view.setModel(self.model)
self.view.viewport().installEventFilter(self)
path = CURRENT_DIR
self.model.setRootPath(path)
self.view.setRootIndex(self.model.index(path))
def eventFilter(self, obj, event):
if (
obj is self.view.viewport()
and event.type() == QtCore.QEvent.MouseButtonDblClick
):
ix = self.view.indexAt(event.pos())
if not ix.isValid():
print("empty area")
self.view.clearSelection()
return super(MainWindow, self).eventFilter(obj, event)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())

pyside key event invalid

I'm trying to write an image display function that instantiates the following class and renders the image when I double-click the image, I wanted to close the window by pressing ESC, but it didn't seem to work. The keyPressEvent function was written before copying. It worked before, but it didn't work here. I'm sad.
class ImageLabel(QtGui.QWidget):
def __init__(self, imagePath, parent=None):
super(ImageLabel, self).__init__(parent)
self.imagePath = imagePath
self.initUI()
def initUI(self):
from PIL import Image
pic_size = (Image.open(self.imagePath).width, Image.open(self.imagePath).height)
self.image_Label = QtGui.QLabel()
self.image_Label.setWindowIcon(QtGui.QIcon(fileconfig.MAIN_ICON))
self.image_Label.resize(pic_size[0] + 50, pic_size[1] + 50)
self.image_Label.setWindowTitle(os.path.basename(self.imagePath))
self.image_Label.setWindowModality(QtCore.Qt.ApplicationModal)
self.image_Label.setPixmap(QtGui.QPixmap(self.imagePath))
self.image_Label.setAlignment(QtCore.Qt.AlignCenter)
self.image_Label.show()
def keyPressEvent(self, event):
key = event.key()
if key == QtCore.Qt.Key_Escape:
self.close()
Here is working code:
from PySide import QtGui,QtCore
import sys
import os
class ImageLabel(QtGui.QWidget):
def __init__(self, imagePath, parent=None):
super(ImageLabel, self).__init__(parent)
self.imagePath = imagePath
self.initUI()
def initUI(self):
from PIL import Image
pic_size = (Image.open(self.imagePath).width,
Image.open(self.imagePath).height)
self.image_Label = QtGui.QLabel()
self.image_Label.setWindowIcon(QtGui.QIcon(fileconfig.MAIN_ICON))
self.image_Label.resize(pic_size[0] + 50, pic_size[1] + 50)
self.image_Label.setWindowTitle(os.path.basename(self.imagePath))
self.image_Label.setWindowModality(QtCore.Qt.ApplicationModal)
self.image_Label.setPixmap(QtGui.QPixmap(self.imagePath))
self.image_Label.setAlignment(QtCore.Qt.AlignCenter)
# self.image_Label.show()
def keyPressEvent(self, event):
key = event.key()
if key == QtCore.Qt.Key_Escape:
self.close()
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
il = ImageLabel('usr/image/img.png')
il.show()
sys.exit(app.exec_())
I just commented one line self.image_Label.show() and everything works fine for me

Drawing a line consisting of multiple points using PyQt

I want to draw a line consisting of multiple points via mouse click in a Python script using PyQt. I need all coordinates of the ponts and I want to be able to delete the line. Here's my script doing all the work, except for the graphical line drawing itself, it just prints what it does:
#!/usr/bin/python3
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class endomess(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.draw = False
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
if self.draw == False:
print('Starting to draw at', str(event.pos()))
self.draw = True
self.linePoints = []
elif self.draw == True:
print('Appending', str(event.pos()))
self.linePoints.append(event.pos())
elif event.button() == Qt.RightButton:
if self.draw == True:
print('Finished drawing. List of all points:', str(self.linePoints))
self.draw = False
def main(argv):
app = QApplication(argv, True)
wnd = endomess()
wnd.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main(sys.argv)
So, here's my problem: how do I actually draw that line that can be defined via the above script? I already had a look at scribble.py and some Qt paint docs, but I don't get it. Probably, this is not a problem for someone more experienced with Qt?
Thanks in advance for all help!
You should probably use the graphics view framework for drawing the lines, rather than attempting to paint them directly.
Here's a basic demo to get you started:
from PyQt4 import QtGui, QtCore
class Window(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.view = View(self)
self.button = QtGui.QPushButton('Clear View', self)
self.button.clicked.connect(self.handleClearView)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.view)
layout.addWidget(self.button)
def handleClearView(self):
self.view.scene().clear()
class View(QtGui.QGraphicsView):
def __init__(self, parent):
QtGui.QGraphicsView.__init__(self, parent)
self.setScene(QtGui.QGraphicsScene(self))
self.setSceneRect(QtCore.QRectF(self.viewport().rect()))
def mousePressEvent(self, event):
self._start = event.pos()
def mouseReleaseEvent(self, event):
start = QtCore.QPointF(self.mapToScene(self._start))
end = QtCore.QPointF(self.mapToScene(event.pos()))
self.scene().addItem(
QtGui.QGraphicsLineItem(QtCore.QLineF(start, end)))
for point in (start, end):
text = self.scene().addSimpleText(
'(%d, %d)' % (point.x(), point.y()))
text.setBrush(QtCore.Qt.red)
text.setPos(point)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Window()
window.resize(640, 480)
window.show()
sys.exit(app.exec_())

Categories