LINUX.ORG.RU

QT. QMediaPlayer в потоке падает

 ,


0

1

Добрый день, хочу запустить QMediaPlayer в потоке, вроде все делаю согласно инструкциям, а он падает. Использую для проигрывания URL

#ifndef WORKER_H
#define WORKER_H

#include <QObject>

#include <QMediaPlayer>
class Worker : public QObject
{
    Q_OBJECT
public:
    explicit Worker(QObject *parent = 0);
    void process();
    QMediaPlayer *mPlayer;

signals:

public slots:
};

#endif // WORKER_H

include "worker.h"

Worker::Worker(QObject *parent) : QObject(parent)
{

}

void Worker::process(){

    QString radioString("http://bfm.hostingradio.ru:8004/fm64");
    mPlayer = new QMediaPlayer();
    mPlayer->setMedia(QMediaContent(QUrl(radioString)));
    mPlayer->setVolume(50);
    mPlayer->play();

}

Запускаю поток таким вот образом из метода MainWindow


 thread = new QThread();
    worker = new Worker();
    worker->moveToThread(thread);
    QObject::connect(thread, &QThread::started, worker, &Worker::process);
    thread->start();
Все начинает работать только когда комментирую //worker->moveToThread(thread)


падает он у вас, скорее всего, при попытке выделить память. Сделайте создание mPlayer - заранее в не потока.

Silerus ★★★ ()
Ответ на: комментарий от Silerus

У меня задача выяснить причину, что не так и почему. Вроде прошелся отладчиком, падает через некоторое время после вызова play. Опять же, если не делать moveToThread, то все успешно работает.

da17 ()
Ответ на: комментарий от Silerus
void MainWindow::playUrl() {

    thread = new QThread();
    worker = new Worker();
    worker->mPlayer = new QMediaPlayer();
    worker->moveToThread(thread);
    QObject::connect(thread, &QThread::started, worker, &Worker::process);
    thread->start();
}

Если я вас правильно понял, вот так сделал. Падает

da17 ()
Ответ на: комментарий от Silerus

Если честно, я даже не знаю, что это. Пока пользуюсь отладчиком cdb. Сборку делаю под Qt 5.8.0 MSVC 2013, сейчас попробую под mingw скомпилировать и посмотреть что будет.

da17 ()
Ответ на: комментарий от da17

у gdb(cdb - это ncureses шкурка для gdb) есть команда backtrace ее надо выполнить после подения, естественно программа должна быть собранна в debug, она отобразит что предшествавало подению. strace - утилита отслеживающая все внутренние вызовы программы, если запустить программу через strace - то можно наблюдать процесс работы из нутри, и увидеть процесс падения

Silerus ★★★ ()
Ответ на: комментарий от anonymous

не такого быть не может, тогда у нас будет застопорен на время вполнения основной поток и мы не сможем управлять этим плеером

Silerus ★★★ ()
Ответ на: комментарий от Silerus

Хорошо, тогда подскажите, если бы там не QMediaPlayer был, а что-то другое, я правильно реализую концепцию потоков в QT.

da17 ()
Ответ на: комментарий от da17

и так у меня заработало, но объект mediaplayer я создал не динамически лови исходники.

//main.cpp
#include "mainwindow.h"
#include "media.h"
#include <QApplication>
#include <QMediaPlayer>
#include <QThread>
int main(int argc, char *argv[]) {
  QApplication a(argc, argv);
  MainWindow w;
  w.show();
  media *mediap = new media();
  QThread *thr = new QThread();
  mediap->moveToThread(thr);
  QObject::connect(thr, SIGNAL(started()), mediap, SLOT(start()));
  thr->start();
  return a.exec();
}
//media.h
#ifndef MEDIA_H
#define MEDIA_H

#include <QMediaPlayer>
#include <QObject>
class media : public QObject {
  Q_OBJECT
public:
  explicit media(QObject *parent = nullptr);

private:
  QMediaPlayer player;

signals:

public slots:
  void start();
};

#endif // MEDIA_H

//media.cpp

#include "media.h"

media::media(QObject *parent) : QObject(parent) {}

void media::start() {

  player.setMedia(
      QUrl::fromLocalFile("~/music/megamen/01-mega-man-bass.mp3"));
  player.setVolume(50);
  player.play();
}


Silerus ★★★ ()

А есть ли необходимость в потоке? С QMediaPlayer не имел дело, но мне кажется он не блокирует поток.

[slot] void QMediaPlayer::play()
Start or resume playing the current source.

Блокирующих слотов что-то не припоминаю. Выглядит всё это асинхронно, возможно даже в недрах и потоки есть(но это не точно).

Blastbit ()
Ответ на: комментарий от Blastbit

есть есть, у меня сейчас 8 нитей создалось. Хотя я создавал 2, основную и куда увел класс пускалку

Silerus ★★★ ()
Ответ на: комментарий от da17

Хочу добавить, что у меня на первой машине файлы успешно проигрываются, проблема появилась при проигрывание интернет радио.

da17 ()
Ответ на: комментарий от Blastbit

А есть ли необходимость в потоке? С QMediaPlayer не имел дело, но мне кажется он не блокирует поток.

[slot] void QMediaPlayer::play() Start or resume playing the current source. Блокирующих слотов что-то не припоминаю. Выглядит всё это асинхронно, возможно даже в недрах и потоки есть(но это не точно).

Может быть и нет, но это я буду дальше разбираться, просто натолкнулся на подобного рода подобный участок в чужом проекте, решил исследовать.

da17 ()
Ответ на: комментарий от da17

В общем я нашел ошибку, только не могу понять в чем именно заключается.

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QFile>
#include <QMainWindow>
#include <QMediaPlayer>
#include <QThread>
#include "worker.h"
namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:

    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    QMediaPlayer mPlayer;
    bool loadUrl();
    Worker *worker;
    QThread *thread;
    void playUrl();
private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H
Оказывается в MainWindow одним из членов класса является объект QMediaPlayer c именем mPlayer, наверное забыл после экспериментов удалить, объект с таким же именем имеется и у класса Worker(только в данном случае mPlayer указатель на объект QMediaPlayer). Что произошло, для меня загадка, но после удаления члена класса из MainWindow все заработало

da17 ()
Ответ на: комментарий от da17

Добрые люди подсказали, что QMediaPlayer некорректно ведет себя, будучи запущенным в стороннем потоки и в принципе потоков не требует, т.к. сам их и создает.

da17 ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.