音乐播放器崩溃 PyQt6

问题描述 投票:0回答:1

我通过单击“添加到播放列表”来加载播放列表。当我单击列表中的任何项目时,播放器工作正常。但如果我尝试单击列表中的另一首曲目,程序就会崩溃。 我注意到以下因素:

  1. 我单击某个曲目,然后再次单击它,一切正常,我可以从列表中选择任何其他曲目,而不会崩溃。
  2. 我单击某个曲目,然后使用滑块位置或按钮快退音乐,我可以从列表中选择任何其他曲目,也不会崩溃。
  3. 但是,如果我单击某个曲目,然后单击另一个曲目而不倒回第一个选定的曲目,程序就会崩溃。
  4. 此外,每次选择新曲目时,我都注意到这种类型的错误:[mp3float @ 000001A17DE3A040] 无法更新跳过样本的时间戳。

我尝试修复它,但没有成功。预先感谢您。

import os
import sys
from PyQt6.QtCore import Qt, QUrl, QTimer
from PyQt6.QtMultimedia import QMediaPlayer, QAudioOutput, QAudio
from PyQt6.QtWidgets import QApplication, QWidget, QPushButton, QSlider, QVBoxLayout, QHBoxLayout, QLabel, QFileDialog, \
    QListWidget, QListWidgetItem


class MusicPlayer(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Music Player")
        self.setGeometry(100, 100, 400, 200)
        self.initUI()
        self.initPlayer()
        self.initSlider()
        self.initTimer()

    def initTimer(self):
        self.tmr0 = QTimer()
        self.tmr0.timeout.connect(self.on_time)
        # self.tmr0.setInterval(5000)
        self.tmr0.start(1)

    def on_time(self):
        if not self.position_slider.isSliderDown():
            pos = self.player.position()
            self.position_slider.setSliderPosition(pos)

    def initSlider(self):
        self.position_slider.setMaximum(self.player.duration())
        self.position_slider.setToolTip("Позиция трека")

    def initPlayer(self):
        self.player = QMediaPlayer()
        self.playlist = []
        self.audio_output = QAudioOutput()
        self.player.setAudioOutput(self.audio_output)
        self.saved_volume = 0.5
        self.audio_output.setVolume(self.saved_volume)

    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.setMinimum(0)
        self.volume_slider.setMaximum(100)
        self.volume_slider.setToolTip("Volume")
        self.volume_slider.valueChanged.connect(self.set_volume)

        self.position_slider = QSlider(Qt.Orientation.Horizontal)
        self.position_slider.setToolTip("Position")
        # self.position_slider.sliderMoved.connect(self.set_position)
        self.position_slider.sliderReleased.connect(self.on_slider_release)

        self.backward_button = QPushButton("<< 10 sec")
        self.backward_button.clicked.connect(self.backward_music)

        self.forward_button = QPushButton("10 sec >>")
        self.forward_button.clicked.connect(self.forward_music)

        self.select_file_button = QPushButton("Add to playlist")
        self.select_file_button.clicked.connect(self.select_file)

        self.clear_playlist_button = QPushButton("Clear playlist")
        self.clear_playlist_button.clicked.connect(self.clear_playlist)

        self.playlist_widget = QListWidget()
        self.playlist_widget.itemDoubleClicked.connect(self.play_selected_track)

        self.track_label = QLabel("Track name")

        vbox = QVBoxLayout()
        hbox1 = QHBoxLayout()
        hbox2 = QHBoxLayout()
        hbox3 = QHBoxLayout()

        hbox1.addWidget(self.play_button)
        hbox1.addWidget(self.pause_button)
        hbox1.addWidget(self.stop_button)
        hbox1.addWidget(self.volume_slider)

        hbox2.addWidget(self.backward_button)
        hbox2.addWidget(self.position_slider)
        hbox2.addWidget(self.forward_button)

        hbox3.addWidget(self.track_label)
        hbox3.addWidget(self.select_file_button)
        hbox3.addWidget(self.clear_playlist_button)

        vbox.addWidget(self.playlist_widget)
        vbox.addLayout(hbox3)
        vbox.addLayout(hbox1)
        vbox.addLayout(hbox2)
        self.setLayout(vbox)

    def select_file(self):
        folder_path = QFileDialog.getExistingDirectory(self, "Выбрать папку с музыкальными файлами", "")
        if folder_path:
            files = [os.path.join(folder_path, file) for file in os.listdir(folder_path) if
                     file.endswith(('.mp3', '.wav', '.ogg'))]
            file_names = [file for file in os.listdir(folder_path) if file.endswith(('.mp3', '.wav', '.ogg'))]
            for file in files:
                self.playlist.append(file)

            for file_name in file_names:
                item = QListWidgetItem(file_name)
                self.playlist_widget.addItem(item)

    def play_music(self):
        item = self.playlist_widget.currentItem()
        index = self.playlist_widget.row(item)
        if self.player.playbackState() == QMediaPlayer.PlaybackState.PausedState:
            self.player.play()
        else:
            if (self.playlist):
                url = QUrl.fromLocalFile(self.playlist[index])  # Создаем объект QUrl из строки с путем к файлу
                self.player.durationChanged.connect(self.initSlider)
                self.player.setSource(url)
                self.audio_output.setVolume(self.saved_volume)
                self.player.play()

    def play_selected_track(self, item):
        index = self.playlist_widget.row(item)
        if 0 <= index < len(self.playlist):
            url = QUrl.fromLocalFile(self.playlist[index])
            self.player.setSource(url)
            self.player.durationChanged.connect(self.initSlider)
            self.audio_output.setVolume(self.saved_volume)
            self.player.play()

    def pause_music(self):
        self.player.pause()

    def stop_music(self):
        self.player.stop()

    def set_volume(self):
        volume = self.volume_slider.value()
        self.saved_volume = self.real_volume(volume)
        self.audio_output.setVolume(self.saved_volume)

    """Метод конвертации значения слайдера (от 0 до 100) 
        к виду (от 0.0 до 1.0) и преобразование шкалы громкости
         в логарифмическую(удобную для восприятия человеком)"""

    def real_volume(self, slider_value):
        return QAudio.convertVolume(
            slider_value * .01,
            QAudio.VolumeScale.LogarithmicVolumeScale,
            QAudio.VolumeScale.LinearVolumeScale
        )
    def backward_music(self):
        position_m = max(0, self.player.position() - 10000)
        self.player.setPosition(position_m)

    def forward_music(self):
        position_m = min(self.player.duration(), self.player.position() + 10000)
        self.player.setPosition(position_m)

    def on_slider_release(self):
        self.player.setPosition(self.position_slider.value())

    def clear_playlist(self):
        self.playlist_widget.clear()
        self.playlist.clear()


app = QApplication(sys.argv)
playerM = MusicPlayer()
playerM.show()
sys.exit(app.exec())

我认为在选择新曲目之前可能需要重置源,但我没有找到该命令。 我想在不崩溃的情况下改变轨道。我还注意到它在第 180 行崩溃了:self.player.setSource(url)

python pyqt pyqt6
1个回答
0
投票
我找到了某种解决方案。在设置新的播放源之前,我会停止播放器,然后检查播放器是否已停止。之后,我使用

QTimer.singleShot 延迟调用函数

self.player.stop() if self.player.playbackState() == QMediaPlayer.PlaybackState.StoppedState: QTimer.singleShot(1, lambda: self.source_setter(url)) def source_setter(self, url): self.player.setSource(url) self.player.play()
    
© www.soinside.com 2019 - 2024. All rights reserved.