I can't change volume of playing music with slider.
I tried to change volume with audio_output, but it doesn't work.
import sys
from PyQt6.QtCore import Qt, QUrl
from PyQt6.QtMultimedia import QMediaPlayer, QAudioOutput
from PyQt6.QtWidgets import QApplication, QWidget, QPushButton, QSlider, QVBoxLayout, QHBoxLayout, QLabel
class MusicPlayer(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Музыкальный плеер")
self.setGeometry(100, 100, 400, 200)
self.initUI()
self.initPlayer()
def initPlayer(self):
self.player = QMediaPlayer()
self.audio_output = QAudioOutput()
self.player.setAudioOutput(self.audio_output)
file_name = "song.mp3"
self.player.setSource(QUrl.fromLocalFile(file_name))
self.audio_output.setVolume(50)
self.player.play()
def initUI(self):
self.play_button = QPushButton("Play")
self.play_button.clicked.connect(self.play_music)
self.pause_button = QPushButton("Pause")
self.pause_button.clicked.connect(self.pause_music)
self.stop_button = QPushButton("Stop")
self.stop_button.clicked.connect(self.stop_music)
self.volume_slider = QSlider(Qt.Orientation.Horizontal)
self.volume_slider.setValue(50)
self.volume_slider.setMaximum(100)
self.volume_slider.setToolTip("Volume")
self.volume_slider.valueChanged.connect(self.set_volume)
self.track_label = QLabel("Название трека")
vbox = QVBoxLayout()
hbox = QHBoxLayout()
hbox.addWidget(self.play_button)
hbox.addWidget(self.pause_button)
hbox.addWidget(self.stop_button)
hbox.addWidget(self.volume_slider)
vbox.addWidget(self.track_label)
vbox.addLayout(hbox)
self.setLayout(vbox)
def play_music(self):
self.player.play()
def pause_music(self):
self.player.pause()
def stop_music(self):
self.player.stop()
def set_volume(self):
self.volume = self.volume_slider.value()
print(self.volume)
print(type(self.volume))
self.audio_output.setVolume(self.volume)
app = QApplication(sys.argv)
playerM = MusicPlayer()
playerM.show()
sys.exit(app.exec())
The documentation of the volume
property of QAudioOutput explains it quite clearly:
The volume is scaled linearly, ranging from 0 (silence) to 1 (full volume).
This means that you need to change the range accordingly: if you aim for a full scale of 0-100, then the value must be divided by 100.
Since multiplication is usually faster than division, for simple ratios like these it's normally preferable to multiply by 0.01 (1/100) instead.
class MusicPlayer(QWidget):
...
def initPlayer(self):
...
self.audio_output.setVolume(.5) # 50 / 100
...
def set_volume(self):
self.volume = self.volume_slider.value()
self.audio_output.setVolume(self.volume * .01)
The documentation also notes that the volume value is linear, but human perception of volume is logarithmic, so you should consider the static QAudio.convertVolume()
:
from PyQt6.QtMultimedia import QMediaPlayer, QAudioOutput, QAudio
...
class MusicPlayer(QWidget):
...
def real_volume(self, slider_value):
return QAudio.convertVolume(
slider_value * .01,
QAudio.VolumeScale.LogarithmicVolumeScale,
QAudio.VolumeScale.LinearVolumeScale
)
def initPlayer(self):
...
self.audio_output.setVolume(self.real_volume(50))
def set_volume(self):
self.volume = self.volume_slider.value()
self.audio_output.setVolume(self.real_volume(self.volume))