QMediaPlayer.setPosition 如何适用于 mp3?

Posted

技术标签:

【中文标题】QMediaPlayer.setPosition 如何适用于 mp3?【英文标题】:How QMediaPlayer.setPosition works for mp3? 【发布时间】:2020-08-03 15:21:02 【问题描述】:

当我尝试从某个位置播放歌曲时遇到问题:它不起作用(歌曲从头开始播放)。

仅当歌曲是“mp3”歌曲而不是“m4a”歌曲时才会出现此问题(它们是我测试的唯一格式)。

问题似乎来自 qt(或 PyQt ?)但我不确定,这是一个最小的例子,我错过了什么吗?

from PyQt5.QtWidgets import QApplication
from PyQt5.QtMultimedia import QMediaContent, QMediaPlayer
from PyQt5.QtCore import QUrl

if __name__ == "__main__":
    app = QApplication([])

    player = QMediaPlayer()
    media_content = QMediaContent(QUrl.fromLocalFile("path_to_my_music_file.mp3"))
    player.setMedia(media_content)
    player.setPosition(10000)
    player.play()

    app.exec_()

【问题讨论】:

【参考方案1】:

setMedia() 是异步的:

注意:该函数在录制完指定的媒体源后立即返回。 它不等待媒体完成加载,也不检查错误。监听 mediaStatusChanged() 和 error() 信号,以便在媒体加载和加载过程中发生错误时得到通知。

由于 MP3 文件的性质,Qt 可能需要一些时间才能正确查找。不幸的是,据我所知,这只能在播放文件一段时间后完成。

一种可能的解决方案是连接到一个自定义函数,该函数延迟 setPosition 直到媒体变得可搜索。

这是一个应该处理的子类(我只测试了 mp3 文件,所以你应该尝试使用其他文件类型以确保它正常工作)。

class Player(QMediaPlayer):
    _delayedPos = 0
    def setPosition(self, pos):
        super().setPosition(pos)
        if pos and not self.isSeekable():
            self._delayedPos = pos
            try:
                # ensure that the connection is done only once
                self.seekableChanged.connect(self.delaySetPosition, Qt.UniqueConnection)
            except:
                pass
        else:
            self._delayedPos = 0

    def delaySetPosition(self, seekable):
        if seekable:
            self.setPosition(self._delayedPos)
        try:
            # just to be safe, in case the media changes before the previous one
            # becomes seekable
            self.seekableChanged.disconnect(self.delaySetPosition)
        except:
            pass

【讨论】:

以上是关于QMediaPlayer.setPosition 如何适用于 mp3?的主要内容,如果未能解决你的问题,请参考以下文章