QMediaPlayer setSource & play causing long hangs
-
Whenever
setSource
andplay
are called on a QMediaPlayer object when connecting to a high-latency live stream (particularly in regards to bandwidth limits), the entire application hangs until it can find the connection, at which point sometimes it doesn't even find one and just barrels along after like 10 seconds.This is entirely not ideal as these functions need to be called frequently and at-will as a user-expedited process. Having random hangs for 10 seconds at a time is bad for users who need a lot of these reconnected at one time.
Is there any way to:
a. make the call to play/setSource asynchronous, so the connection does its own thing in a separate thread, or
b. don't wait for it at all, keep the application running until a connection is establishedTo prevent these hangs?
-
Nevermind, I figured it out...
So it seems that
setSource
reasonably expects you to actually have stopped the media beforehand. Doing so and adding a small wait works like a charm and fixes this issue!Relevant example.
m_player->stop(); QThread::msleep(100); m_player->setSource(url); m_player->play();
-
Hi,
Which version of Qt are you using ?
On which platform ? -
@SGaist Qt 6.6.0. This occurs on both Windows and Linux. Unsure if it occurs on MacOS, but given the circumstances of high-latency, bandwidth-limited streams I expect it to happen there too.
-
@ChrisW67 I really don't know any reproducible streams. The issue moreso lies in the fact that it's synchronously waiting for the connection to be established and stable and pausing the exec loop entirely.
@swurl said in QMediaPlayer setSource & play causing long hangs:
I really don't know any reproducible streams
Then how do you test and know that you have long hangs?
-
@swurl said in QMediaPlayer setSource & play causing long hangs:
I really don't know any reproducible streams
Then how do you test and know that you have long hangs?
-
@jsulm The streams are confined to the specific ecosystem of FRC. If you have a remote camera server running that streams latent MJPG streams, however, you should get the same results.
@swurl More specifically, some streams coming from this ecosystem tend towards very high (>400ms) latency with really long connection times, particularly due to strict bandwidth limitations of 4Mbps. I think you can recreate this through an artificially high ping when connecting, not sure how to create that though.
-
S SGaist referenced this topic on
-
@swurl More specifically, some streams coming from this ecosystem tend towards very high (>400ms) latency with really long connection times, particularly due to strict bandwidth limitations of 4Mbps. I think you can recreate this through an artificially high ping when connecting, not sure how to create that though.
@swurl To establish any TCP connection over a link where packets take greater than 400mS to transit from one end to the other is going to take at least 3 times that period (a SYN, SYN/ACK, ACK handshake). So with an unreliable connection establishment time > 1.2 seconds and a what I assume is a 10-second timeout baked into the Qt library, you will occasionally fall foul of it. Qt cannot make a slow line or remote server faster, or make an unreliable link reliable.
Since you have not provided example code and stream it is hard to say what can be done to improve the situation.
Can you at least disclose exactly how you are setting the source for the media player?
Are you passing it an already open and running QIODevice or relying on the media code to open a stream from a URL? The former option is the only approach I can think of that might decouple the opening and the playing. -
@swurl To establish any TCP connection over a link where packets take greater than 400mS to transit from one end to the other is going to take at least 3 times that period (a SYN, SYN/ACK, ACK handshake). So with an unreliable connection establishment time > 1.2 seconds and a what I assume is a 10-second timeout baked into the Qt library, you will occasionally fall foul of it. Qt cannot make a slow line or remote server faster, or make an unreliable link reliable.
Since you have not provided example code and stream it is hard to say what can be done to improve the situation.
Can you at least disclose exactly how you are setting the source for the media player?
Are you passing it an already open and running QIODevice or relying on the media code to open a stream from a URL? The former option is the only approach I can think of that might decouple the opening and the playing.@ChrisW67 said in QMediaPlayer setSource & play causing long hangs:
Qt cannot make a slow line or remote server faster, or make an unreliable link reliable.
This I fully understand. However, loading on a browser takes <2 seconds. I'm curious if I'm doing something wrong regarding how I'm doing it.
I'm simply using
setSource
andplay
right now.I'll try the QIODevice thing though, and let you know how it goes...
-
@swurl To establish any TCP connection over a link where packets take greater than 400mS to transit from one end to the other is going to take at least 3 times that period (a SYN, SYN/ACK, ACK handshake). So with an unreliable connection establishment time > 1.2 seconds and a what I assume is a 10-second timeout baked into the Qt library, you will occasionally fall foul of it. Qt cannot make a slow line or remote server faster, or make an unreliable link reliable.
Since you have not provided example code and stream it is hard to say what can be done to improve the situation.
Can you at least disclose exactly how you are setting the source for the media player?
Are you passing it an already open and running QIODevice or relying on the media code to open a stream from a URL? The former option is the only approach I can think of that might decouple the opening and the playing. -
Nevermind, I figured it out...
So it seems that
setSource
reasonably expects you to actually have stopped the media beforehand. Doing so and adding a small wait works like a charm and fixes this issue!Relevant example.
m_player->stop(); QThread::msleep(100); m_player->setSource(url); m_player->play();
-
-
You could also use the playbackState property to trigger the new play once it gets in the stopped state.