Issue
I got a problem when I try to play a song from a certain position: it does'nt work (the song plays from the beginning).
This problem only occurs when the song is a 'mp3' song, not a 'm4a' one (they're the only format I tested).
The problem seems to come from qt (or PyQt ?) but I'm not sure, here's a minimal example, do I miss something ?
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_()
Solution
setMedia()
is asynchronous:
Note: This function returns immediately after recording the specified source of the media. It does not wait for the media to finish loading and does not check for errors. Listen for the mediaStatusChanged() and error() signals to be notified when the media is loaded and when an error occurs during loading.
It's possible that, due to the nature of MP3 files, Qt takes some time before being able to correctly seek. Unfortunately, as far as I can tell, this can only be done after some amount of time has passed after playing the file.
A possible solution is to connect to a custom function that delays the setPosition until the media becomes seekable.
This is a subclass that should take care of it (I only tested with mp3 files, so you should try it with other file types to ensure that it works properly).
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
Answered By - musicamante
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.