前文
以下はすべてQtバージョン5.3.1のコンテキスト(現時点で最も関連性の高いもの)で提供されていますが、5.xブランチのどのバージョンのコンテキストでも、場合によっては4.8.xでも意味があります(不要としてチェックしなかった)。
オペレーティングシステム-Windows、開発環境-MinGWおよびgcc 4.8.2と組み合わせたQtCreator 3.1.2他のプラットフォーム/ IDE /コンパイラの使用から本質は変わりません。
ビデオデータのソースとして、最も単純な利用可能なオプション、つまりデスクトップが選択されました。 つまり アプリケーションは、デスクトップで発生するすべてのコピーを表示します。 マルチモニター構成では、ソースとしてメイン画面を使用します。
それでは始めましょう
出発点として、ドキュメント「ビデオの概要:低レベルビデオフレームの操作」を読むことができます。
この記事からのいくつかのポイント:
- ビデオソースはQObjectの子孫でなければなりません。
- タイプQAbstractVideoSurface *のプロパティvideoSurfaceを宣言する必要があります。
- 再生を開始する前に、QVideoSurfaceFormatを渡してQAbstractVideoSurface :: startを呼び出す必要があります。
- 各フレームを表示するには、QVideoFrameを渡してQAbstractVideoSurface :: presentを呼び出す必要があります。
- ムービーの再生が終了したら、QAbstractVideoSurface :: stopを呼び出す必要があります。
コードを書く
新しいプロジェクト「Qt Quick Application」を作成しています。 将来的にはC ++を使用してQmlコンポーネントを作成するため、このタイプのアプリケーションを選択することが重要です。
次に、QObjectの子孫であるクラスを作成し、展開を開始します。
結果が判明する限り、それは非常にシンプルで簡潔です。大量の水を注ぐのではなく、いくつかのコメントを付けてコードを提供します:
DesktopVideoProducer.h:
#pragma once #include <QAbstractVideoSurface> #include <QVideoSurfaceFormat> class DesktopVideoProducer : public QObject { Q_OBJECT public: // Qml static void registerQmlType(); explicit DesktopVideoProducer( QObject *parent = 0 ); ~DesktopVideoProducer(); // property, Q_PROPERTY( QAbstractVideoSurface* videoSurface READ videoSurface WRITE setVideoSurface ) QAbstractVideoSurface* videoSurface() const; void setVideoSurface( QAbstractVideoSurface* s ); protected: void timerEvent( QTimerEvent* ); private: void closeSurface(); private: QAbstractVideoSurface* _surface; QVideoSurfaceFormat _format; };
DesktopVideoProducer.cpp:
#include "DesktopVideoProducer.h" #include <QtQml/qqml.h> #include <QApplication> #include <QScreen> #include <QDesktopWidget> void DesktopVideoProducer::registerQmlType() { // DesktopVideoProducer, // 0.1, DesktopVideoProducer. // QtCreator, // . // @uri DesktopVideoProducer qmlRegisterType<DesktopVideoProducer>( "DesktopVideoProducer", 0, 1, "DesktopVideoProducer" ); } DesktopVideoProducer::DesktopVideoProducer( QObject *parent ) : QObject( parent ), _surface( 0 ) { startTimer( 1000 / 15 ); //15 fps } DesktopVideoProducer::~DesktopVideoProducer() { closeSurface(); } QAbstractVideoSurface* DesktopVideoProducer::videoSurface() const { return _surface; } void DesktopVideoProducer::setVideoSurface( QAbstractVideoSurface* s ) { closeSurface(); _surface = s; } void DesktopVideoProducer::closeSurface() { if( _surface && _surface->isActive() ) _surface->stop(); } void DesktopVideoProducer::timerEvent( QTimerEvent* ) { if( !_surface ) return; QScreen* screen = QGuiApplication::primaryScreen(); QDesktopWidget* desktop = QApplication::desktop(); if( !screen || !desktop ) return; // screenshot QVideoFrame QPixmap screenPixmap = screen->grabWindow( desktop->screen()->winId() ); QImage screenImage = screenPixmap.toImage(); QVideoFrame::PixelFormat pixelFormat = QVideoFrame::pixelFormatFromImageFormat( screenImage.format() ); // - ( )- // () surface if( screenPixmap.size() != _format.frameSize() || pixelFormat != _format.pixelFormat() ) { closeSurface(); _format = QVideoSurfaceFormat( screenPixmap.size(), pixelFormat ); _surface->start( _format ); } // _surface->present( QVideoFrame( screenImage ) ); }
main.qml:
import QtQuick 2.2 import QtQuick.Window 2.1 import QtMultimedia 5.0 import DesktopVideoProducer 0.1 Window { visible: true width: 360 height: 360 DesktopVideoProducer { id: videoProducer; } VideoOutput { anchors.fill: parent; source: videoProducer; } }
main.cpp:
#include <QApplication> #include <QQmlApplicationEngine> #include"DesktopVideoProducer.h" int main(int argc, char *argv[]) { // DesktopVideoProducer Qml DesktopVideoProducer::registerQmlType(); // QApplication::desktop() QGuiApplication //QGuiApplication app(argc, argv); QApplication app(argc, argv); QQmlApplicationEngine engine; engine.load(QUrl(QStringLiteral("qrc:///main.qml"))); return app.exec(); }
PS:完全なプロジェクトはGitHubからダウンロードできます 。