ffpyplayer
ffpyplayer copied to clipboard
MediaPlayer Sound Still Coming From Speaker After player.set_mute(True)
I wrote a script in Python 3.8 on a Windows 10 platform that uses MediaPlayer to play a video in a PyQt5 QLabel. I can toggle pause by pressing the "P" key on the keyboard but I cannot toggle mute when pressing the "M" key.
When pressing the "M" key, the player.get_mute() return changes from False to True to False just as I expect it to, but sound keeps coming out of the speaker regardless if player.get_mute() == True
Here is a minimal script that exhibits this behavior.
from PyQt5.QtWidgets import QLabel, QMainWindow, QApplication, QWidget
from PyQt5.QtWidgets import QShortcut
from PyQt5.QtGui import QPixmap, QImage, QKeySequence
from PyQt5.QtCore import QTimer, Qt
import os, sys
from ffpyplayer.player.player import MediaPlayer
class VideoCap(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Mute Test")
self.central_widget = QWidget()
self.setCentralWidget(self.central_widget)
self.central_widget.setGeometry(10,50,960,720)
self.player = MediaPlayer('test.mp4')
self.setGeometry(25,50,960,720)
self.vidWindow = QLabel(self.central_widget)
self.vidWindow.setGeometry(0,0,960,720)
self.muteKey = QShortcut(QKeySequence(Qt.Key_M), self)
self.muteKey.activated.connect(self.toggleMute)
self.pauseKey = QShortcut(QKeySequence(Qt.Key_P), self)
self.pauseKey.activated.connect(self.togglePause)
self.show()
self.start()
def nextFrameSlot(self):
try:
frame, val = self.player.get_frame()
if val != 'eof':
img, t = frame
data = img.to_bytearray()[0]
width, height = img.get_size()
qimage = QImage(data, width, height, QImage.Format_RGB888)
pix = QPixmap.fromImage(qimage)
pix = pix.scaled(self.vidWindow.width(), self.vidWindow.height(), Qt.KeepAspectRatio, Qt.SmoothTransformation)
self.vidWindow.setPixmap(pix)
except:
pass
def toggleMute(self):
isMuted = self.player.get_mute()
print('Muted = ', isMuted)
if isMuted == True:
self.player.set_mute(False)
print('Should now be unmuted')
else:
self.player.set_mute(True)
print('Should now be muted')
def togglePause(self):
isPaused = self.player.get_pause()
print('Paused = ', isPaused)
if isPaused == True:
self.player.set_pause(False)
print('Should now be playing')
else:
self.player.set_pause(True)
print('Should now be paused')
def start(self): # Control the timer for calling nextframeslot
frame_rate = 30.0
rate = int(1000.0 / frame_rate)
self.timer = QTimer()
self.timer.setTimerType(Qt.PreciseTimer)
self.timer.timeout.connect(self.nextFrameSlot)
self.timer.start(rate)
def closeEvent(self, event):
event.ignore()
self.player.close_player()
os._exit(0)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = VideoCap()
app.exec()
Please note that when I pasted in the code block above, I couldn't get the import lines nor the if __name__ == __main__ in the code block. Also, the underscores in if __name__ == __main__ got stripped out. Weird.
I'm not sure what the issue is. But can you try not checking get_mute and instead unconditionally set mute to true and see if it works? Also, try setting the volume to zero and back to 1 if that doesn't work!?
I changed the toggleMute() method to ` def toggleMute(self):
self.player.set_mute(True)`
and it still did not mute.
Then I tried your suggestion to setting the volume to 0 and 1 with this code: ` def toggleMute(self):
playerVolume = self.player.get_volume()
print('Volume = ', playerVolume)
if playerVolume == 0.0:
self.player.set_volume(1.0)
print('Should now be unmuted')
else:
self.player.set_volume(0.0)
print('Should now be muted')`
and IT WORKED!
I'll just go with setting volume instead of setting mute. Thanks for the suggestion!
Also, please close the issue if you believe the issue is unique to me. Otherwise, it might be something you still want to investigate. Either way s fine with me - I have a solution. Thanks again!
I'll leave it open as it's a bug in ffpyplayer and I'll fix it at some point. But basically, https://github.com/matham/ffpyplayer/blob/master/ffpyplayer/player/core.pyx#L1543 needs to check if it's muted, but it doesn't for sdl2.
I had the same issue, on Windows10, just using ffpyplayer and opencv in a fairly basic script. Works just using the set volume thing; can save/restore the previous volume easy enough also, so not a major issue.
#class or global variable
prevVolume = 1
# in control loop
if player.get_volume() > 0:
prevVolume = player.get_volume()
player.set_volume(0)
else:
player.set_volume(prevVolume)