首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Qt::QMediaPlayer:如何禁用帧缓冲以减少RTSP流延迟或延迟?

Qt::QMediaPlayer:如何禁用帧缓冲以减少RTSP流延迟或延迟?
EN

Stack Overflow用户
提问于 2021-11-02 06:35:20
回答 1查看 576关注 0票数 0

当我使用Qt的QMediaPlayer和C++来播放RTSP流时,它总是只在缓冲区状态达到100帧之后才显示帧。这通常会造成3~5秒的延迟。

如何禁用缓冲区或将缓冲区设置为零以减少延迟?在这个问题上,我对QMediaPlayer无能为力。

需要你的帮助。

cpp代码:

代码语言:javascript
运行
复制
#include "stdafx.h"
#include <QVideoSurfaceFormat>
//#include "Qxtglobalshortcut/QxtGlobalShortcut.h"
#include "qnetworkinterface.h"
#include "AmbaRemoteCam.h"
#include "controls/AliceMessageBox.hpp"

#include "cam_cali/cam_cali.h"
#include "camera/camera.h"
using namespace Cam;

AmbaRemoteCam::AmbaRemoteCam(QWidget* parent)
    : QMainWindow(parent)
    , m_titleBar(nullptr)
    , m_trayIcon(nullptr)
{
    // layout
    m_mainLayout = new(std::nothrow) QVBoxLayout();
    m_mainLayout->setContentsMargins(20, 20, 20, 20);
    m_mainLayout->setSpacing(10);

    // Settings
    m_mainLayout->addWidget(new MLabel(tr("Settings:")));
    m_video_view = nullptr;
    {
        MLabel* label = new MLabel(tr("RTSP Video:"));
        m_mediaUrl = new MEditor(CAM_DEFAULT_RTSP);
        m_btnConnectRtsp = new QPushButton(tr("Connect"));
        m_btnConnectRtsp->setObjectName("normal_button");
        m_btnConnectRtsp->setFixedSize(100, 30);
        connect(m_btnConnectRtsp, SIGNAL(clicked()), this, SLOT(slot_btnConnectRtsp_Clicked()));

        QHBoxLayout* layout0 = new QHBoxLayout();
        layout0->setContentsMargins(20, 0, 0, 0);
        layout0->setSpacing(10);
        layout0->addWidget(label);
        layout0->addWidget(m_mediaUrl);
        layout0->addWidget(m_btnConnectRtsp);

        m_video_view = new QVideoWidget();
        m_video_view->setObjectName("video_widget");
        m_video_view->setFixedSize(1280, 724);
        m_video_view->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
        m_player = new QMediaPlayer(/*m_video_view, QMediaPlayer::LowLatency*/);
        m_player->setVideoOutput(m_video_view);
        connect(m_player, &QMediaPlayer::mediaStatusChanged, this, &AmbaRemoteCam::slot_mediaStateChanged);
        connect(m_player, &QMediaPlayer::positionChanged, this, &AmbaRemoteCam::slot_positionChanged);

        m_mainLayout->addLayout(layout0);
        m_mainLayout->addWidget(m_video_view);
    }

    m_msgPos = nullptr;
    {
        QHBoxLayout* layout = new QHBoxLayout();
        layout->setSpacing(10);

        m_msgStat = new MLabel("");
        layout->addWidget(new MLabel(tr("Play State: ")));
        layout->addWidget(m_msgStat);

        m_msgPos = new MLabel("");
        layout->addWidget(new MLabel(tr("Play Pos: ")));
        layout->addWidget(m_msgPos);

        m_msgRate = new MLabel("");
        layout->addWidget(new MLabel(tr("Rate: ")));
        layout->addWidget(m_msgRate);

        m_msgBufferStatus = new MLabel("");
        layout->addWidget(new MLabel(tr("BufferStatus: ")));
        layout->addWidget(m_msgBufferStatus);

        m_msgError = new MLabel("");
        layout->addWidget(new MLabel(tr("Error: ")));
        layout->addWidget(m_msgError);

        layout->addStretch();

        m_mainLayout->addLayout(layout);
    }

    m_mainLayout->addStretch();

    // UI
    ui.setupUi(this);

    // Set the mainLayout as the root layout
    ui.centralWidget->setObjectName("widget_main_window");
    ui.centralWidget->setLayout(m_mainLayout);

    // windows icon
    setWindowIcon(QIcon(":/AmbaRemoteCam/Resources/alice.png"));

    retranslateUi();
}

AmbaRemoteCam::~AmbaRemoteCam()
{
}

void AmbaRemoteCam::retranslateUi()
{
    //m_fullScreenBtn->setToolTip(tr("Full Screen")); 
}

void AmbaRemoteCam::slot_mediaStateChanged(QMediaPlayer::MediaStatus state)
{
    const char* MediaStatusString[]=
    {
        "UnknownMediaStatus",
        "NoMedia",
        "LoadingMedia",
        "LoadedMedia",
        "StalledMedia",
        "BufferingMedia",
        "BufferedMedia",
        "EndOfMedia",
        "InvalidMedia"
    };

    printf("slot_mediaStateChanged, MediaStatus:%s\n", MediaStatusString[state]);
    m_msgStat->setText(QString(MediaStatusString[state]));
    m_msgError->setText(m_player->errorString());
}

void AmbaRemoteCam::slot_positionChanged(qint64 position)
{
    printf("slot_positionChanged, position: %ld\n", position);
    m_msgPos->setText(QString::number(position));
    m_msgRate->setText(QString::number(m_player->playbackRate()));
    m_msgBufferStatus->setText(QString::number(m_player->bufferStatus()));
}

void AmbaRemoteCam::slot_btnConnectRtsp_Clicked()
{
    m_player->setMedia(QUrl(m_mediaUrl->text()));
    m_player->setPlaybackRate(60);
    m_player->play();
}

.h文件:

代码语言:javascript
运行
复制
#ifndef AMBAREMOTECAM_H
#define AMBAREMOTECAM_H

#include <QtWidgets/QMainWindow>
#include <QtWidgets>
#include <QLayout>
#include <QToolBar>
#include <QMediaPlayer>
#include <QMediaPlaylist>
#include <QVideoWidget>
#include "ui_AmbaRemoteCam.h"
#include "MEditor.hpp"
#include "mlabel.hpp"

#include "_inl.hpp"

class AmbaRemoteCam : public QMainWindow
{
    Q_OBJECT
public:
    AmbaRemoteCam(QWidget *parent = 0);
    ~AmbaRemoteCam();

signals:

public slots:
    void slot_mediaStateChanged(QMediaPlayer::MediaStatus state);
    void slot_positionChanged(qint64 position);
    void slot_btnConnectRtsp_Clicked();

private:
    void retranslateUi();

private:
    QVBoxLayout* m_mainLayout;
    Ui::AmbaRemoteCamClass ui;

    QVideoWidget* m_video_view;
    QMediaPlayer* m_player;
    MEditor* m_mediaUrl;
    QPushButton* m_btnConnectRtsp;
    MLabel* m_msgStat;
    MLabel* m_msgRate;
    MLabel* m_msgBufferStatus;
    MLabel* m_msgPos;
    MLabel* m_msgError;
};

#endif
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-11-03 02:06:49

终于来了!

在经历了多次海难和尝试之后,我终于找到了一种奇怪的方法来解决这个问题:

使用'setPlaybackRate()‘将播放速率设置为0,其他值则大于实际fps,以防止RTSP缓冲。

代码语言:javascript
运行
复制
void AmbaRemoteCam::slot_btnConnectRtsp_Clicked()
{
    m_player->setMedia(QUrl(m_mediaUrl->text()));
    m_player->setPlaybackRate(0);
    m_player->play();
}

没有人会想到使用这种方法来防止RTSP缓冲。

希望下一个版本的QMediaPlayer有一个更人性化的界面来解决这个问题。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69806233

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档