當我使用 Qt 的 QMediaPlayer 和 C 播放 RTSP 流時,它總是在緩沖區狀態達到 100 幀后才顯示幀。這通常會延遲 3~5 秒。
如何禁用緩沖或將緩沖區設定為零以推斷延遲?對于這個問題,我對 QMediaPlayer 無能為力。
需要你的幫助...
cpp代碼:
#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 檔案:
#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
uj5u.com熱心網友回復:
最后!
經過大量的搜索和嘗試,我終于找到了一種解決此問題的奇怪方法:
使用 'setPlaybackRate()' 將播放速率設定為零,然后設定一個大于實際 fps 的值以防止 RTSP 緩沖。
void AmbaRemoteCam::slot_btnConnectRtsp_Clicked()
{
m_player->setMedia(QUrl(m_mediaUrl->text()));
m_player->setPlaybackRate(0);
m_player->play();
}
沒有人會想到使用這種方法來防止 RTSP 緩沖。
希望下一個版本的 QMediaPlayer 有一個更人性化的界面來解決這個問題。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/354363.html
