Qt应用程序开发五:QMediaPlayer播放视频,提取视频帧,多窗口播放同一视频

效果图:

方法一:QMediaPlayer+QVideoWidget (如果其他格式视频播放不出来,安装一个视频解码器可以解决)

#include "QMutPlayer.h"
#include "ui_QMutPlayer.h"
#include<QFileDialog>
#include<QDebug>

QMutPlayer::QMutPlayer(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::QMutPlayer)
{
    ui->setupUi(this);
    mVideoPlayer = new QMediaPlayer(this);
    mSurfacePlayer = new QMediaPlayer(this);
    mVideoWidget  = new QVideoWidget(ui->lab_videowidget);
    mVideoPlayer->setVideoOutput(mVideoWidget);
}

QMutPlayer::~QMutPlayer()
{
    delete ui;
}

void QMutPlayer::on_btn_select_video_clicked()
{
    QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"),"", tr("video (*.mp4 *.wav *.avi)"));
    if(fileName.isEmpty())
        return;
    mVideoPlayer->setMedia(QUrl(fileName));
    mVideoPlayer->play();

}

void QMutPlayer::showEvent(QShowEvent *event)
{
    Q_UNUSED(event)
    mVideoWidget->resize(ui->lab_videowidget->size());
}


方法二:QMediaPlayer+ QAbstractVideoSurface 提取视频帧 

然后将视频帧转化为QImage,用QML 和QLabel 加载,或者QWidget 的paintEvent 绘画出来

//提取视频帧

#ifndef VIDEOSURFACE_H
#define VIDEOSURFACE_H

#include <QObject>
#include<QAbstractVideoSurface>

class VideoSurface : public QAbstractVideoSurface
{
    Q_OBJECT
public:
    explicit VideoSurface(QObject *parent = 0);
signals:

    void showImage(QImage img);

protected:
        bool present(const QVideoFrame &frame);
    QList<QVideoFrame::PixelFormat> supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType = QAbstractVideoBuffer::NoHandle) const;
};

#endif // VIDEOSURFACE_H


#include "VideoSurface.h"
#include<QPixmap>
VideoSurface::VideoSurface(QObject *parent) : QAbstractVideoSurface(parent)
{

}

QList<QVideoFrame::PixelFormat> VideoSurface::supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType) const
{
    Q_UNUSED(handleType);
    QList<QVideoFrame::PixelFormat> listPixelFormats;
        listPixelFormats << QVideoFrame::Format_RGB32
            << QVideoFrame::Format_BGR32;
        return listPixelFormats;

}

 bool VideoSurface::present(const QVideoFrame &frame)
 {
     if (frame.isValid())
         {
             QVideoFrame cloneFrame(frame);
             cloneFrame.map(QAbstractVideoBuffer::ReadOnly);
             QImage recvImage(cloneFrame.bits(), cloneFrame.width(), cloneFrame.height(), QVideoFrame::imageFormatFromPixelFormat(cloneFrame.pixelFormat()));
             cloneFrame.unmap();
             emit showImage(recvImage);
             return true;
         }
         return false;

 }

//调用

    mSurfacePlayer = new QMediaPlayer(this);
    mVideoSurface = new VideoSurface(this);
    mSurfacePlayer->setVideoOutput(mVideoSurface);
    connect(mVideoSurface,SIGNAL(showImage(QImage)),SLOT(onShowImage(QImage)));
/QML 刷新图片 需要用到QQuickImageProvider 


#ifndef IMAGEPROVIDER_H
#define IMAGEPROVIDER_H


#include <QQuickImageProvider>
class ImageProvider : public QQuickImageProvider
{

public:
    explicit ImageProvider();
public:
    void addImage(QImage &image);


    QPixmap requestPixmap(const QString &id, QSize *size, const QSize &requestedSize);

    QImage  requestImage(const QString &id, QSize *size, const QSize &requestedSize);

private:

    QImage mImage;

};

#endif // IMAGEPROVIDER_H


#include "ImageProvider.h"

ImageProvider::ImageProvider(): QQuickImageProvider(QQuickImageProvider::Image)
{

}

void ImageProvider::addImage(QImage &image)
{
    mImage = image;
}

QPixmap ImageProvider::requestPixmap(const QString &id, QSize *size, const QSize &requestedSize)
{
    return QPixmap::fromImage(mImage);
}

QImage ImageProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
{
    return mImage;
}


#ifndef SHOWIMAGE_H
#define SHOWIMAGE_H

#include <QObject>
#include"ImageProvider.h"

class ShowImage : public QObject
{
    Q_OBJECT
public:
      static ShowImage *instance();
    ~ShowImage();
      ImageProvider *m_pImgProvider;
      void setImage(QImage image);
  signals:
      void callQmlRefeshImg();
private:
      ShowImage(QObject *parent = 0);
      static ShowImage *mShowImage;
};

#endif // SHOWIMAGE_H


#include "ShowImage.h"

ShowImage* ShowImage::mShowImage = NULL;

ShowImage:: ShowImage(QObject *parent) : QObject(parent)
{
    m_pImgProvider = new ImageProvider();
}

ShowImage *ShowImage::instance()
{
    if(mShowImage == NULL)
        mShowImage = new ShowImage;
    return mShowImage;
}

ShowImage::~ShowImage()
{
    delete m_pImgProvider;
}

void ShowImage::setImage(QImage image)
{
    m_pImgProvider->addImage(image);
    emit callQmlRefeshImg();
}


#ifndef QMLLOADWIDGET_H
#define QMLLOADWIDGET_H

#include <QWidget>
#include<QQuickWidget>


class QmlLoadWidget : public QQuickWidget
{
    Q_OBJECT
public:
    explicit QmlLoadWidget(QWidget *parent = 0);
signals:
    void errMessage(QString msg);
public slots:
     void addImage(QImage image);
     void getErr(QQuickWindow::SceneGraphError error, const QString &message);

};

#endif // QMLLOADWIDGET_H


#include "QmlLoadWidget.h"
#include<QQmlEngine>
#include<QQmlContext>
#include"ShowImage.h"

QmlLoadWidget::QmlLoadWidget(QWidget *parent) : QQuickWidget(parent)
{
    this->resize(parent->size());
    setResizeMode(QQuickWidget::SizeRootObjectToView);
    rootContext()->setContextProperty("CodeImage",ShowImage::instance());
    engine()->addImageProvider("CodeImg",ShowImage::instance()->m_pImgProvider);
    setSource(QUrl("qrc:/QmlRender/LoadVideImage.qml"));


}

void QmlLoadWidget::addImage(QImage image)
{
    ShowImage::instance()->setImage(image);
}

void QmlLoadWidget::getErr(QQuickWindow::SceneGraphError error, const QString &message)
{
    emit errMessage(message);
}

 

完整代码下载地址:https://download.csdn.net/download/xzpblog/10960022

Qt是一个跨平台的图形用户界面(GUI)开发工具集,可以用来开发各种应用程序,包括音视频播放器。 QMediaPlayerQt中的一个多媒体播放类,可以用来播放音频和视频文件。基于QMediaPlayer,我们可以开发一个功能完善的音视频播放器。 首先,我们可以使用QMediaPlayer提供的功能来实现基本的音视频播放控制,包括播放、暂停、停止、快进、快退等。我们可以通过按钮、菜单或者快捷键来触发相应的操作,或者可以根据用户的输入来实现自动播放和暂停。 其次,我们可以通过QMediaPlayer的信号和槽机制来实现一些附加功能。例如,当播放播放完一个文件时,我们可以发出一个信号来通知用户,或者自动切换到下一个文件。我们还可以监听播放器的状态变化,例如播放、暂停、停止等,以便更新界面和提供相应的反馈信息。 此外,我们还可以使用QMediaPlayer的媒体查询功能来获取音视频文件的元数据,例如时长、作者、标题等信息,以及获取当前播放位置和进度。我们可以将这些信息显示在界面上,让用户获得更好的使用体验。 除了以上功能,我们还可以使用Qt提供的其他模块来增加更多的特性。例如,我们可以使用Qt Multimedia模块的QAudioProbe来实现音频波形显示,使用Qt MultimediaWidgets模块的QVideoWidget来实现视频播放区域,使用Qt Widgets模块的QSlider来实现视频进度条等。 总之,基于QMediaPlayer开发,我们可以轻松实现一个功能完善的音视频播放器,满足用户对于音视频播放的基本需求,并且具备一定的扩展性,可以根据实际需求进行功能扩展和自定义。
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值