Get signal from when media has ended Qt.Multimedia and QML - qt

I'm creating a music app using only QML and it's going really well and I'm now working on the track queue. I'm using Qt.Multimedia to play the tracks and there is a property that could be used to play next track when the current has ended, but I don't understand how to get the signal.
Here is the doc I'm using: https://qt-project.org/doc/qt-5.0/qtmultimedia/qml-qtmultimedia5-audio.html
There's a EndOfMedia that I was planning of using, but I don't understand how?

It seems reasonable to connect a Slot to the playbackStateChanged() or stopped() signal that checks the status to see if it is EndOfMedia and then plays the next track.

Related

Can I delay/bundle reactions to QPlainTextEditor.textChanged events?

I have a small IDE for a modeling language I wrote, implemented in PyQt/PySide, and am trying to implement a code navigator that let's you jump to different sections in the file being edited.
The current implementation is: (1) connect to QPlainTextEditor.textChanged, (2) any time a change is made, (sloppily) parse the file and update the navigator pane
It seems to work OK, but I'm worried this could cause major performance issues for large files on slower systems, in particular if more stuff is connected to textChanged in the future.
My question: Has anybody here implemented a delayed reaction to events, so that multiple events (i.e. keystrokes) within a short period only trigger a single update (say once per second)? And is there a proper QT way of doing this?
Thanks,
Michael
You can try using timers if you want some "delay".
There would be 2 ways to use them (with different results).
One is only parse after no input has been done for a certain amount of time
NOTE: I only know C++ Qt but I assume the same things are valid for pyqt so this is kind of "pseudocode" I hope you get the concept though.
QTimer timer; //somewhere
timer.setSingleShot(true); //only fire once
connect(timer,QTimer::timeout(),OnTimerDone(...);
OnTextChanged(...)
{
timer.start(500); //wait 500ms
}
OnTimerDone(...)
{
DoStuff(...);
}
This will restart the timer every input, so when you call that and the timer is not done the timeout signal is not emitted. When no input is done for an amount of time the timer timeouts and you parse the file.
The second option would be to have a periodic timer running (singleShot(false)).
Just start the timer for like each second. and timeout will be called once a second. You can combine that with a variable which you set to true when the input changes and to false when the file is parsed. So you avoid parsing when nothing has changed.
In C++Qt you won't have to worry about multi-threading because the slot gets called in the GUI thread. I assume it is the same for python but you should probably check this.

MediaFoundation - Frame is ready?

I am using Media Foundation to play a video, which I need to edit in real time, so I need to know when a frame is ready to be presented, but the callback does not offer such a message.
My only idea is checking the frame rate, then setting a timer to just shy of that and using GetPosition to check where I am against where I was the last time the timer was called, but there must be a better way than this.
Thanks!
Matt
Why can't you inject your own IMFStreamSink instance in the topologoy, do the editing in your implementation of IMFStreamSink::ProcessSample and passing the edited to whatever output node you are using currently?
Also, if you are using EVR, you could make a custom presenter - see this article on MSDN.
I found an easy solution. Set the playback speed on the session, then create a presentation clock from the session. Set a timer, and check the presentation clock. When time has passed equal to the playback speed for one tick, a new frame is being presented.

SampleGrabber callback is getting called spuriously even when graph is paused

I'm using Directshow SampleGrabber in callback mode to capture video frame from source file and do some processing. Also I would like to maintain the current playback rate of video and need to support both random, forward and backward seeking. For this I'm also doing some local buffering in a different thread.
I'm running graph with syn source set to NULL, so as to get maximum speed. However when I pause the graph after fixed amount of buffering. The SampleGrabber callback is getting called spuriously even when graph is paused. This is affecting my frame indexing and tracking. I want to resume the graph exactly from the same position at which it was paused. However if I run the graph with default clock it works fine but then my playback get affected. I want buffering thread to finish as soon as possible.
How can I make sure that callback is not called when graph is paused? Any thoughts or suggestion would be of great help.
Thanks in advance
Pradeep
Paused graph typically has all the same streaming internally (active state) with the exception that renderers are blocking streaming, esp. as soon as enough data is received for a preview banner. Since you removed clock from the graph, your renderer is likely to not block execution because it does not hold any clock to pause against. In your case this is the problem coming out of your intent to reuse the same graph for quick parsing through file and playback. Separate graph design looks having more chances to do better.

Detect activity level of microphone in flex

I have to detect avtivityLevel of microphone in Flex. I am using the activityLevel property of Microphone class but as I found out it always return -1 even if I have done Microphone.getMicrophone().
To detect activity level we have to set microphone.setLoopback = true;
Does anybody know how to do this without using loop back as I do not want to hear my sound back just monitor the activity level
Thanks
The microphone won't show any activity until it is attached to a NetStream connection. You can use a MockNetStream to fake the connection using OSMF - see my answer here.

QNetworkAccessManager handling asynchronous thread

I am new to QT. I have created object class QNetworkAccessManager main window as parent. Also registered to SIGNAL finished. It is working fine.
But I want to know in which thread it will run. Will it block the main thread. If i need to perform sequence of get operation how should I need to write the code.
Please give me some sample to understand concept properly.
It certainly does not run in the main thread, the calls to get() are asynchronous.
For example this would keep firing get requests:
while (condition) {
QNetworkRequest request;
request.setUrl(QUrl(m_ServerURL);
m_httpGetUpdatedFile->get(request);
}
You then have the slot for the finished signal which is processing the QNetworkReply. That slot basically should be getting called for each get request you make (even if it fails). If you need to keep track of when all your get requests have finished, you need to keep a track of how many you posted and then have your own finished flag or signal.
QNAM does use threads in the background, but this is completely invisible for your application code. Everything you see will run in the main thread.
QNAM works in the usual Qt way, it will emit signals when things happen, and you connect these signals to slots in your own code, which do things as much as they can. If they don't for example have enough data, then your slots must not block to wait for new data, instead they must return. And then they will be called again when/if there's more data (or you'll get another signal if for example connection was terminated).
Some links, in case you have not read these:
Qt signal & slot documentation
Qt networking documentation

Resources