0

I have a Phonon.MediaObject that is connected to a web source through Phonon.AudioOutput. Therefore, when running play(), the main GUI freezes until the player starts playing (5 seconds at worst case).

This could be fixed by moving the player, or at least it's web fetching task. I've read online about moveToThread() function, but it doesn't seem to work.

I tried making a thread out of it, but without luck: http://pastebin.com/1iXdQD8Y (written in PyQt)

Any ideas?

iTayb
  • 12,373
  • 24
  • 81
  • 135

3 Answers3

1

This will require a bit more coding on your side.

I don't know python all that well, but from looking at your code I think that one mistake you are making is to assume that your PhononThread class is living in it's own thread, but it's actually living in thread in which it has been created.

I wouldn't even try to move objects like MediaObject between threads. One way to do it would be to create your own QObject descendant, then in it's constructor create all objects that you will need to play music. You will also need to add slots to your class to access every phonon function you will need to call from main thread. REMEMBER to create this object WITHOUT parent object. Then you need to move it to newly created QThread and connect all signals/slots between threads.

I don't use python, but here is pseudo-C++ outline of how it should look like:

class MyPlayer: public QObject{
    Q_OBJECT

public:

    AudioOutput* ao;
    MediaObject* mo;

    MyPlayer() : QObject(0) {    // note no parent QObject instance
        ao = new AudioOutput();
        ... // Create and connect all objects
    }

public slots:

    void setCurrentSource ( const MediaSource & source ){
        mo->setCurrentSource(source);
    }
    // And other methods that are not slots already.
};

Then in your application you do:

MyPlayer* mp = new MyPlayer();
QThread* th = new QThread();

connect(th, SIGNAL(finished()), mp, SLOT(deleteLater()));

connect( mainThreadObj, SIGNAL(setPlayerSource ( const MediaSource & ) ), mp, SLOT(setPlayerSource ( const MediaSource & ) ) );
... // and other signals; note that methods that are signals already can be conected witout wrappers:
connect( mainThreadObj, SIGNAL(playerPlay() ), mp->mo, SLOT(play()) );

mp->moveToThread(th);

For stopping your thread, just connect signal from your main thread to th's quit() slot, and emit it when needed.

j_kubik
  • 6,062
  • 1
  • 23
  • 42
0

Subclass QThread, reimplement run() with the stuff you want to happen in your thread, and then create an instance of your thread and call start() on it.

Just be careful about when you connect to things in your thread or from your thread, because you don't want to do a direct or auto connection, you want to do a queued connection in most cases.

This link shows two ways to use QThread, one as I just described, and it links to another producer consumer example using moveToThread().

what is the correct way to implement a QThread... (example please...)

Hope that helps.

Community
  • 1
  • 1
phyatt
  • 18,472
  • 5
  • 61
  • 80
  • If the whole player lives in a different thread, output will still reach the audio card? – iTayb Feb 22 '13 at 23:51
  • When I do, i get the following error: `WARNING: bool __thiscall Phonon::FactoryPrivate::createBackend(void) phonon back end plugin could not be loaded` – iTayb Feb 23 '13 at 12:51
  • https://bugs.archlinux.org/task/27850 apparently, the phonon folder isn't linked the way it used to... what OS are you on? – phyatt Feb 24 '13 at 04:02
  • You could go and copy the backend folder to your exe folder, `C:/Qt/4.8.4/plugins/phonon_backend` so that next to your exe, there is a folder called `phonon_backend`, with the appropriate dlls in it. – phyatt Feb 26 '13 at 20:47
  • I don't think it's the case. I've already done it in order to make the first phonon code to work. Everything still running from the same process and directory. – iTayb Feb 26 '13 at 20:52
  • Can you post any of the source code that creates the error? It might be something with Phonon needs to be initially loaded by the main thread for some reason... – phyatt Feb 26 '13 at 21:05
  • I've tried this code: http://pastebin.com/1iXdQD8Y , now i have no warning but nothing happens... – iTayb Feb 27 '13 at 09:45
0

Have you tried QtConcurrent::run? It runs function in a separate thread.

http://qt-project.org/doc/qt-4.8/qtconcurrentrun.html#run or check it here https://stackoverflow.com/search?q=QtConcurrent%3A%3Arun

Community
  • 1
  • 1
Shf
  • 3,463
  • 2
  • 26
  • 42