用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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章