PyQt6 How to set volume with slider

61 views Asked by At

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())
2

There are 2 answers

0
musicamante On BEST ANSWER

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))
2
S. Nick On

Sorry, I have PyQt5.
Set up your imports and try:

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
'''
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent
from PyQt5.Qt import *


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)
#        self.player.setSource(QUrl.fromLocalFile(file_name))
#        self.audio_output.setVolume(50)

# +++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
        file_name = "sounds/zvuki_prirody.mp3"   # "song.mp3" eустановите свое 
        file = QUrl.fromLocalFile(file_name)
        self.content = QMediaContent(file)
        self.player.setMedia(self.content)
        self.player.setVolume(50.0)
# +++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        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()

# ---------------------> vvvvvv <----------------------------------------------
    def set_volume(self, volume):
#        self.volume = self.volume_slider.value()
#        self.audio_output.setVolume(self.volume)

        self.player.setVolume(volume)                              # +++ volume


if __name__ == "__main__":
    app = QApplication(sys.argv)
    playerM = MusicPlayer()
    playerM.show()
    sys.exit(app.exec())

enter image description here