vlcframe.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. import platform
  2. import sys
  3. import vlc
  4. from PyQt5 import QtWidgets, QtGui, QtCore
  5. class VlcFrame(QtWidgets.QFrame):
  6. def __init__(self, master=None):
  7. super().__init__(master)
  8. # Create a basic vlc instance
  9. self.instance = vlc.Instance()
  10. self.media = None
  11. # Create an empty vlc media player
  12. self.mediaplayer = self.instance.media_player_new()
  13. self.create_ui()
  14. self.is_paused = False
  15. def create_ui(self):
  16. """Set up the user interface, signals & slots
  17. """
  18. self.widget = QtWidgets.QWidget(self)
  19. # In this widget, the video will be drawn
  20. if platform.system() == "Darwin": # for MacOS
  21. self.videoframe = QtWidgets.QMacCocoaViewContainer(0)
  22. else:
  23. self.videoframe = QtWidgets.QFrame()
  24. self.palette = self.videoframe.palette()
  25. self.palette.setColor(QtGui.QPalette.Window, QtGui.QColor(0, 0, 0))
  26. self.videoframe.setPalette(self.palette)
  27. self.videoframe.setAutoFillBackground(True)
  28. self.positionslider = QtWidgets.QSlider(QtCore.Qt.Horizontal, self)
  29. self.positionslider.setToolTip("Position")
  30. self.positionslider.setMaximum(1000)
  31. self.positionslider.sliderMoved.connect(self.set_position)
  32. self.positionslider.sliderPressed.connect(self.set_position)
  33. self.hbuttonbox = QtWidgets.QHBoxLayout()
  34. self.playbutton = QtWidgets.QPushButton("Play")
  35. self.hbuttonbox.addWidget(self.playbutton)
  36. self.playbutton.clicked.connect(self.play_pause)
  37. self.stopbutton = QtWidgets.QPushButton("Stop")
  38. self.hbuttonbox.addWidget(self.stopbutton)
  39. self.stopbutton.clicked.connect(self.stop)
  40. self.hbuttonbox.addStretch(1)
  41. self.volumeslider = QtWidgets.QSlider(QtCore.Qt.Horizontal, self)
  42. self.volumeslider.setMaximum(100)
  43. self.volumeslider.setValue(self.mediaplayer.audio_get_volume())
  44. self.volumeslider.setToolTip("Volume")
  45. self.hbuttonbox.addWidget(self.volumeslider)
  46. self.volumeslider.valueChanged.connect(self.set_volume)
  47. self.vboxlayout = QtWidgets.QVBoxLayout()
  48. self.vboxlayout.addWidget(self.videoframe)
  49. self.vboxlayout.addWidget(self.positionslider)
  50. self.vboxlayout.addLayout(self.hbuttonbox)
  51. self.widget.setLayout(self.vboxlayout)
  52. # Add actions to file menu
  53. open_action = QtWidgets.QAction("Load Video", self)
  54. close_action = QtWidgets.QAction("Close App", self)
  55. open_action.triggered.connect(self.open_file)
  56. close_action.triggered.connect(sys.exit)
  57. self.timer = QtCore.QTimer(self)
  58. self.timer.setInterval(100)
  59. self.timer.timeout.connect(self.update_ui)
  60. def play_pause(self):
  61. """Toggle play/pause status
  62. """
  63. if self.mediaplayer.is_playing():
  64. self.mediaplayer.pause()
  65. self.playbutton.setText("Play")
  66. self.is_paused = True
  67. self.timer.stop()
  68. else:
  69. if self.mediaplayer.play() == -1:
  70. self.open_file()
  71. return
  72. self.mediaplayer.play()
  73. self.playbutton.setText("Pause")
  74. self.timer.start()
  75. self.is_paused = False
  76. def stop(self):
  77. """Stop player
  78. """
  79. self.mediaplayer.stop()
  80. self.playbutton.setText("Play")
  81. def open_file(self):
  82. """Open a media file in a MediaPlayer
  83. """
  84. dialog_txt = "Choose Media File"
  85. filename = QtWidgets.QFileDialog.getOpenFileName(self, dialog_txt, os.path.expanduser('~'))
  86. if not filename:
  87. return
  88. # getOpenFileName returns a tuple, so use only the actual file name
  89. self.media = self.instance.media_new(filename[0])
  90. # Put the media in the media player
  91. self.mediaplayer.set_media(self.media)
  92. # Parse the metadata of the file
  93. self.media.parse()
  94. # Set the title of the track as window title
  95. self.setWindowTitle(self.media.get_meta(0))
  96. # The media player has to be 'connected' to the QFrame (otherwise the
  97. # video would be displayed in it's own window). This is platform
  98. # specific, so we must give the ID of the QFrame (or similar object) to
  99. # vlc. Different platforms have different functions for this
  100. if platform.system() == "Linux": # for Linux using the X Server
  101. self.mediaplayer.set_xwindow(int(self.videoframe.winId()))
  102. elif platform.system() == "Windows": # for Windows
  103. self.mediaplayer.set_hwnd(int(self.videoframe.winId()))
  104. elif platform.system() == "Darwin": # for MacOS
  105. self.mediaplayer.set_nsobject(int(self.videoframe.winId()))
  106. self.play_pause()
  107. def set_volume(self, volume):
  108. """Set the volume
  109. """
  110. self.mediaplayer.audio_set_volume(volume)
  111. def set_position(self):
  112. """Set the movie position according to the position slider.
  113. """
  114. # The vlc MediaPlayer needs a float value between 0 and 1, Qt uses
  115. # integer variables, so you need a factor; the higher the factor, the
  116. # more precise are the results (1000 should suffice).
  117. # Set the media position to where the slider was dragged
  118. self.timer.stop()
  119. pos = self.positionslider.value()
  120. self.mediaplayer.set_position(pos / 1000.0)
  121. self.timer.start()
  122. def update_ui(self):
  123. """Updates the user interface"""
  124. # Set the slider's position to its corresponding media position
  125. # Note that the setValue function only takes values of type int,
  126. # so we must first convert the corresponding media position.
  127. media_pos = int(self.mediaplayer.get_position() * 1000)
  128. self.positionslider.setValue(media_pos)
  129. # No need to call this function if nothing is played
  130. if not self.mediaplayer.is_playing():
  131. self.timer.stop()
  132. # After the video finished, the play button stills shows "Pause",
  133. # which is not the desired behavior of a media player.
  134. # This fixes that "bug".
  135. if not self.is_paused:
  136. self.stop()