本文内容截止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
#include
#include
#include
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
#include
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::"<
#include "USBCamCapture.h"
#include
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