解决PyQt5 QMediaPlayer播放mp3后占用的问题

Posted 哦...

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了解决PyQt5 QMediaPlayer播放mp3后占用的问题相关的知识,希望对你有一定的参考价值。

先看使用PyQt5的QMediaPlayer播放MP3文件的代码片段:

def play_media(self,filename):
    abs_path = os.path.abspath(filename)
    url = qtc.QUrl.fromLocalFile(abs_path)
    c = QMediaContent(url)
    self.media_player.setMedia(c)
    self.media_player.play()

代码的说明:

  1. 方法出自继承了QMainWindow的自定义类。
  2. 指定路径时,一定要使用绝对路径!PyQt5中凡是涉及路径的问题一律都要用绝对路径。
  3. QMediaPlayer播放的是QMediaContent。所以要将文件路径转为QUrl,然后再将QUrl转为QMediaContent。

为了可以反复使用QMediaPlayer对象,所以将QMediaPlayer对象定义为类的属性:

def __init__(self, myui):
        super().__init__(parent=None)
        ...省略部分代码
        self.media_player = QMediaPlayer(self)

代码的说明:

创建QMediaPlayer对象时,必须指定所属的parent对象。

创建窗口对象后,使用窗口的play_media函数就可以播放指定的mp3文件了:

win.win.play_media('my.mp3')

当my.mp3文件播放完毕后,想要通过I/O修改my.mp3产生新文件内容时,会产生错误:

PermissionError: [Errno 13] Permission denied

 产生这个错误的原因是因为my.mp3文件还处于被占用状态,所以无法进行修改。这是Windows系统的底层机制导致的。

解决的方式就是当QMediaPlayer播放完my.mp3形成的QMediaContent后后,用一个“新的”QMediaContent将其替换下来,然后就能修改my.mp3了。

如何才能知道QMediaPlayer的播放状态呢?QMediaPlayer在开始播放、暂停播放、停止播放时会产生stateChanged信号:

  • 播放时发射的信号内容是QMediaPlayer.PlayingState

  • 暂停时发射的信号内容是QMediaPlayer.PausedState

  • 停止时发射的信号内容是QMediaPlayer.StoppedState

通过指定槽函数,在收到QMediaPlayer.StoppedState信号内容时,更改播放器中的QMediaContent即可:

def __init__(self, myui):
    super().__init__(parent=None)
    ...省略部分代码
    self.media_player = QMediaPlayer(self)
    self.media_player.stateChanged.connect(self.do_mediaplayer_statechanged)

代码说明:

QMediaPlayer的stateChanged信号的槽函数是do_mediaplayer_statechanged

def do_mediaplayer_statechanged(self, state):
        if state == QMediaPlayer.PlayingState:
            # print('player is playing')
            pass
        if state == QMediaPlayer.PausedState:
            # print('player is pausing')
            pass
        if state == QMediaPlayer.StoppedState:
            # print('player is stopped')
            self.media_player.setMedia(QMediaContent())

代码说明:

一旦接收到QMediaPlayer.StoppedState信号时,创建一个空的QMediaContent作为self.media_player的新内容。这样就把播放已结束的内容替换掉了。

替换结束后,既可以通过I/O修改my.mp3的内容了。修改完毕后,再次调用play_media函数时,会将新的my.mp3内容作为QMediaContent进行播放。

以上是关于解决PyQt5 QMediaPlayer播放mp3后占用的问题的主要内容,如果未能解决你的问题,请参考以下文章

PyQt5:QMediaPlayer 无法从 QBuffer 重放音频

QMediaPlayer setPlaybackRate > 1 导致高音音频

PyQt5 - 在新窗口中打开 QMediaplayer 并播放视频

PyQt5 QMediaPlayer播放不了视频

pyqt5音频播放

尝试使用 QMediaPlayer 添加声音事件