首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用QMediaPlayer播放流

如何使用QMediaPlayer播放流
EN

Stack Overflow用户
提问于 2015-05-28 12:59:47
回答 2查看 13.3K关注 0票数 12

我已经设置了服务器和视频流,以便可以使用以下命令行通过ffplay连接到流:

代码语言:javascript
复制
ffplay rtmp://<IP>/path

是否可以使用QMediaPlayer QMediaContent或其他东西连接到此流?

或者我可以用ffserver创建任何其他类型的流。

使用与ffplay相同的路径将导致“不支持的url方案!”

通过进一步的实验,我尝试了ffserver服务器流,但以MFStreamer::doRead()中的Qt崩溃而告终。

显然,它应该叫BeginRead的MFStreamer,但它没有。

如何使用QMediaPlayer播放视频流?

编辑:这是我的代码

videotest.cpp

代码语言:javascript
复制
#include "videotest.h"
#include <QVBoxLayout>
#include <QVideoWidget>
#include <qmediaplayer.h>
#include <QMediaContent>
#include <QNetworkAccessManager>
#include <QNetworkReply>

struct VideoTest::Private
{
    QMediaPlayer * mediaPlayer;
    QNetworkAccessManager * networkAccessManager;
    QNetworkReply * reply;
};

VideoTest::VideoTest(QWidget *parent)
    : QMainWindow(parent)
{
    d = new Private;
    d->mediaPlayer = new QMediaPlayer(this, QMediaPlayer::StreamPlayback);
    d->networkAccessManager = new QNetworkAccessManager(this);
    ui.setupUi(this);

    QVideoWidget * videoWidget = new QVideoWidget(ui.centralWidget);
    videoWidget->show();
    QPalette palette = videoWidget->palette();
    palette.setColor(QPalette::Background, QColor(0, 0, 0));
    videoWidget->setPalette(palette);

    ui.videoLayout->addWidget(videoWidget);
    d->mediaPlayer->setVideoOutput(videoWidget);

    connect(ui.playButton, SIGNAL(clicked()), d->mediaPlayer, SLOT(play()));
    connect(ui.pauseButton, SIGNAL(clicked()), d->mediaPlayer, SLOT(pause()));
    connect(ui.videoUrlEdit, SIGNAL(editingFinished()), this, SLOT(sourceChanged()));
    connect(d->mediaPlayer, SIGNAL(error()), this, SLOT(stateChanged()));
    connect(d->mediaPlayer, SIGNAL(stateChanged), this, SLOT(stateChanged()));
}

VideoTest::~VideoTest()
{
    delete d;
}

void VideoTest::sourceChanged()
{
    d->reply = d->networkAccessManager->get(QNetworkRequest(ui.videoUrlEdit->text()));
    if(d->reply)
    {
        connect(d->reply, SIGNAL(readyRead()), this, SLOT(networkRequestReady()));
    }
}

void VideoTest::stateChanged()
{
    QString text = ui.textEdit->toPlainText();
    text.append("\n").append(d->mediaPlayer->errorString()).append(" : ").append(d->mediaPlayer->mediaStatus());
    ui.textEdit->setText(text);
}

void VideoTest::networkRequestReady()
{
    d->mediaPlayer->setMedia(QMediaContent(), d->reply);
}

视频测试.h

代码语言:javascript
复制
#ifndef VIDEOTEST_H
#define VIDEOTEST_H

#include <QtWidgets/QMainWindow>
#include "ui_videotest.h"

class VideoTest : public QMainWindow
{
    Q_OBJECT

public:
    VideoTest(QWidget *parent = 0);
    ~VideoTest();

public slots:
    void sourceChanged();
    void stateChanged();
    void networkRequestReady();

private:
    Ui::VideoTestClass ui;
    struct Private;
    Private * d;
};

#endif // VIDEOTEST_H
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-06-05 07:17:06

我找到了办法让它起作用。

我放弃了Qt。Qt的工作人员坚持认为它应该工作,但是无法产生任何可以工作的配置。他们说如果你从VLC源源不断的话,它应该能工作,但是我没有让它工作。我还尝试了ffmpeg、ffserver和nginx流。我让这些东西与mplayer,ffplay,VLC,甚至Windows一起使用,但从未使用过QMediaPlayer。

我试着把网址给setMedia。我尝试制作一个定制的QIODevice来读取流数据,并将该数据提供给使用StreamPlayback初始化的QMediaPlayer,但是它无法成功地读取数据。

最后,我所需要的只是播放一个流,是一个QWidget,而不是GPL许可。

我使用了libVLCvlc-qt,它们都工作得很好。

遵循vlc-qt/windows/vlc_headers/2.2/很容易,但是您需要记住将头文件从这些指示复制到vlc/sdk/include/vlc/plugins (原文如此)。这一点很重要,如果不这样做,您可能会在编译过程中出现错误。注意,如果平台的不同版本与我的不匹配,这些路径可能是不同的。而且,当你读这篇文章的时候,它可能是不必要的。

VideoTest.h

代码语言:javascript
复制
#ifndef VIDEOTEST_H_
#define VIDEOTEST_H_

#include <QtWidgets/QMainWindow>
#include "ui_videotest.h"

class VideoTest: public QMainWindow
{
    Q_OBJECT

    public:
        VideoTest(QWidget * p_parent = 0);
        ~VideoTest();

    public slots:
        void sourceChanged();

    private:
        struct Private;
        Private * d;
        Ui::VideoTestClass ui;
};

#endif

videotest.cpp

代码语言:javascript
复制
#include "videotest.h"

#include <vlc-qt/Common.h>
#include <vlc-qt/Instance.h>
#include <vlc-qt/Media.h>
#include <vlc-qt/MediaPlayer.h>
#include <vlc-qt/WidgetVideo.h>

struct VideoTest::Private
{
    VlcInstance * vlcInstance;
    VlcMediaPlayer * vlcMediaPlayer;
    VlcMedia * vlcMedia;
    VlcWidgetVideo * vlcVideoWidget;
};

VideoTest::VideoTest(QWidget * p_parent)
{
    d = new Private();
    ui.setupUi(this);

    d->vlcMedia = 0;
    d->vlcInstance = new VlcInstance(VlcCommon::args(), this);
    d->vlcMediaPlayer = new VlcMediaPlayer(d->vlcInstance);
    d->vlcVideoWidget = new VlcWidgetVideo(this);

    d->vlcMediaPlayer->setVideoWidget(d->vlcVideoWidget);
    d->vlcVideoWidget->setMediaPlayer(d->vlcMediaPlayer);

    ui.videoLayout->addWidget(d->vlcVideoWidget);

    connect(ui.playButton, SIGNAL(clicked()), d->vlcMediaPlayer, SLOT(play()));
    connect(ui.pauseButton, SIGNAL(clicked()), d->vlcMediaPlayer, SLOT(pause()));
    connect(ui.videoUrlEdit, SIGNAL(editingFinished()), this, SLOT(sourceChanged()));
}

VideoTest::~VideoTest()
{
    delete d->vlcInstance;
    delete d->vlcMediaPlayer;
    delete d->vlcMedia;

    delete d;
}

VideoTest::sourceChanged()
{
    QUrl url(ui.videoUrlEdit->test());
    if(url.isValid() == false)
    {
        return;
    }

    d->vlcMediaPlayer->stop();

    delete d->vlcMedia;
    d->vlcMedia = new VlcMedia(url.toString(), d->vlcInstance);
    d->vlcMediaPlayer->open(d->vlcMedia);
}

VideoTest.ui

做你自己的,我不为你工作

只需确保它有插入视频小部件的pauseButton、playButton、videoUrlEdit(QLineEdit)和videoLayout。

票数 5
EN

Stack Overflow用户

发布于 2019-10-10 11:27:08

我刚刚在QML VideoOutput中使用C++ QMediaPlayer使用setMedia(QUrl("http://127.0.0.1:8080"));播放了流

该流由VLC媒体播放器使用HTTP创建到8080端口。我还成功地将VLC媒体播放器创建的流播放到本地文件,通过setMedia(QMediaContent(), &localFile);将其传递给setMedia(QMediaContent(), &localFile);

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

https://stackoverflow.com/questions/30507317

复制
相关文章

相似问题

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