简体   繁体   English

QAudioOutput 和 QMediaPlayer (PyQt6) 的衰落效果

[英]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.我希望音频在启动或取消暂停时以给定的间隔(例如 0.6 秒)淡入,并在暂停时以相同的间隔淡出。 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).我尝试使用 QThread 来保持我的 ui 响应,同时使用 for 循环逐渐降低音量(迭代 10 次,每次降低音量并睡眠一定时间,0.6 / 10 秒)。 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:如果有人设法解决了这样的问题,请提供帮助,将不胜感激:这是在 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.所以我让它与 QPropertyAnimation 一起工作,仍在处理键值和缓动曲线,但确实很多。 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())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM