解决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进行播放。

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值