延迟而不冻结多媒体

时间:2015-09-05 12:47:33

标签: qt

所以我希望它在特定时间播放视频,所以在play();后我使用函数delay();: 但它冻结了流,所以我只得到音频,没有图像。??? 我无法使用计时器。

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QVideoWidget *videoWidget = new QVideoWidget;
    QBoxLayout *layout = new QVBoxLayout;
    layout->addWidget(videoWidget);
    ui->centralWidget->setLayout(layout);
    p.setVideoOutput(videoWidget);
    filename=QFileDialog::getOpenFileName(this,"select movie","/");
    this->setWindowTitle(filename);
    p.setMedia(QUrl::fromLocalFile(filename));
    p.setPosition(300000);
    p.play();

    delay(4000);
    p.setPosition(p.position()+1800000);
    delay(4000);
    p.setPosition(p.position()+1800000);
    delay(4000);
}
void MainWindow:: delay( int millisecondsToWait )
{
    QEventLoop loop;
     QTimer::singleShot( millisecondsToWait, &loop, SLOT(quit()));
     loop.exec();
}

没有延迟它将正常运行视频,但我希望它每30分钟只播放4秒,我只能获得音频

2 个答案:

答案 0 :(得分:0)

我认为你的方法并不像第一眼看上去那么好,因为它本质上是忙等待。您在最多 100毫秒时提供processEvents。这意味着,如果没有或只有少数事件要处理,它将更早地返回。这意味着,在循环中花费了大量的CPU时间。无论如何,你的线程永远不会空闲。

现在看一下使用QTimer。 QTimer不会像你正在做的那样忙碌等待,而是线程将暂停直到被操作系统唤醒。 QTimer的保证粒度为10毫秒,因此在您的示例中它应该足够好。在这里,我假设millisecondsToWait远大于100,即允许processEvents花费的时间。

因此,问题的一个可能解决方案是将delay()的电话号码替换为QTimer::singleShot(),如下所示:http://doc.qt.io/qt-4.8/qtimer.html#singleShot

现在delay()之后的代码(继续到下一个循环)将在您用于计时器的槽方法中执行。通过使进程异步,允许Qt和操作系统在播放视频时将CPU花在需要的位置。

答案 1 :(得分:0)

如果要在不中断事件循环的情况下执行逐步逻辑,可以使用下一个模式:

void delay( int msec )
{
  QEventLoop loop;
  QTimer::singleShot( msec, &loop, &QEventLoop::quit );
  loop.exec();
}