用Qt5的 QMultiMedia 音频视频采集的限制

本文内容截止Qt5.14版本。

Qt应该很早就提供了MultiMedia 这样一个多媒体开发框架用于开发常见的音视频处理。

比如音乐,视频的播放。 做个简单的音乐视频播放器,在规定的平台,用规定的格式,比如mp3 mac平台播放mp4都没什么问题。

在linux平台,Multimedia需要安装 libpulse-dev依赖库。

所以说,做个简单的有限的格式的播放器,没有什么问题。

做pcm音频采集,在windows linux平台都没什么问题。mac 最好用原生的AVFoundation.

pcm音频播放,windows没什么问题。mac最好还是用原生的API或者OpenAL播放pcm。

但是做视频采集的时候,比如采集摄像头,就有问题了。尤其是windows。

在macOS平台,通过QVideoProbe 回调出来的QVideoFrame是ARGB32格式的。

在windows平台,是不支持QVideoProbe 回调出YUV 或者RGB的。

在Linux上,通过QVideoProbe 回调出来的QVideoFrame是YV12格式的。

为啥在windows上不支持视频采集,官方给出了答案:

翻译过来就是:

Windows的Qt Multimedia能是通过两个插件实现的。一个使用Microsoft DirectShow API,另一个使用WMF(Windows Media Foundation)框架。 DirectShow API在Windows 98中引入,从Windows XP开始逐渐弃用。 Windows Vista中引入了Media Foundation框架,以替代DirectShow和其他多媒体API。因此,仅Windows Vista和更高版本的操作系统才支持Qt中的WMF插件。

限制:
Qt中的WMF插件当前不提供Camera后端。相反,DirectShow插件仅提供对Camera功能的有限支持。支持显示取景器和捕获静止图像等基本功能,但是,大多数Camera控制未实现。

当前不支持视频录制。此外,DirectShow插件不支持任何低级视频功能,例如监视使用QVideoProbe或相关类播放或录制的视频帧。

综上所述,如果我们需要实时采集摄像头的图像,进一步用x264编码。想使用Qt,来偷懒做跨平台开发,目前是做不到的,不同平台还存在很多差异性。所以摄像头采集,可以用OpenCV去做,跨平台,简单。

考虑到Qt良好的跨平台性,在开发项目过程中,可以使用部分稳定可靠的一些简单的功能,比如pcm音频实时采集。其余的功能,都是鸡肋。做音视频开发,还是用更专业的方式吧。需要学习 FFmpeg x264 OpenGL OpenCV 各个平台原生的音视频硬件编解码等。

小广告:

专业音视频开发学习: https://edu.csdn.net/course/detail/2314

快速轻松学习Qt开发: https://edu.csdn.net/course/detail/24587  https://edu.csdn.net/course/detail/27479

附: QtMultiMedia 采集摄像头源码  只支持macOS Linux  windows上会报错,原因上面已经说清楚。

#ifndef USBCAMCAPTURE_H
#define USBCAMCAPTURE_H

#include <QWidget>
#include <QCamera>
#include <QVideoProbe>
#include <QVideoWidget>

class USBCamCapture : public QWidget
{
    Q_OBJECT

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

private:
    QCamera*        m_pUSBCamera;
    QVideoWidget*   m_pPreviewWidget;
    QVideoProbe*    m_pVideoProbe;

private:
    void    releaseCameraResources();

private slots:
    void    onCameraVideoFrameProbed(QVideoFrame frame);

};

#endif // USBCAMCAPTURE_H
#include "USBCamCapture.h"
#include<QHBoxLayout>
#include <QDebug>

USBCamCapture::USBCamCapture(QWidget *parent)
    : QWidget(parent)
{
    this->setWindowTitle("USBCamera Capture");
    this->resize(640,400);

    m_pUSBCamera = new QCamera("",NULL); //input usb cam name or default no name is ok

    m_pPreviewWidget = new QVideoWidget(this);

    QHBoxLayout* mainlayout = new QHBoxLayout();
    mainlayout->addWidget(m_pPreviewWidget);

    m_pUSBCamera->setViewfinder(m_pPreviewWidget);
    m_pUSBCamera->start();

    QCameraViewfinderSettings viewfinderSettings;
    viewfinderSettings.setResolution(640,360);
    viewfinderSettings.setPixelFormat(QVideoFrame::Format_YV12);
    viewfinderSettings.setMaximumFrameRate(30);
    m_pUSBCamera->setViewfinderSettings(viewfinderSettings);

    m_pVideoProbe = new QVideoProbe(m_pUSBCamera);
    connect(m_pVideoProbe, SIGNAL(videoFrameProbed(QVideoFrame)), this, SLOT(onCameraVideoFrameProbed(QVideoFrame)));
    m_pVideoProbe->setSource(m_pUSBCamera);

    this->setLayout(mainlayout);
}

USBCamCapture::~USBCamCapture()
{
    releaseCameraResources();
}

void USBCamCapture::releaseCameraResources()
{
    if(m_pVideoProbe != NULL)
    {
        delete m_pVideoProbe;
        m_pVideoProbe = NULL;
    }

    if(m_pUSBCamera != NULL)
    {
         m_pUSBCamera->stop();
         delete m_pUSBCamera;
         m_pUSBCamera = NULL;
    }
}

void USBCamCapture::onCameraVideoFrameProbed(QVideoFrame videoFrame)
{
    if (!videoFrame.map(QAbstractVideoBuffer::ReadOnly)){
        return;
    }

    qDebug()<<"VideoFrame::"<<videoFrame.pixelFormat()<<videoFrame.width()<<videoFrame.height();
}
#include "USBCamCapture.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    USBCamCapture w;
    w.show();

    return a.exec();
}
#-------------------------------------------------
#
# Project created by QtCreator 2020-01-17T13:14:27
#
#-------------------------------------------------

QT       += core gui multimedia multimediawidgets

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = QtUSBCamera
TEMPLATE = app

DEFINES += QT_DEPRECATED_WARNINGS


SOURCES += \
        main.cpp \
        USBCamCapture.cpp

HEADERS += \
        USBCamCapture.h

发布了33 篇原创文章 · 获赞 14 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/chenchao_shenzhen/article/details/104017499