このページでは

QML 動画のサンプル

動画およびカメラのファインダー表示内容の変換。

「QML Video」では、QMLのVideoOutput およびCamera 型に適用できるさまざまな変換(移動、サイズ変更、回転、アスペクト比の変更)を実演しています。

また、ネイティブコードを QML と組み合わせて、より高度な機能を実装する方法も示しています。この例では、C++ コードを使用して QML のフレームレートを計算しています。この値は、QML 内で、動画コンテンツの上に重ねられた半透明のアイテムとしてレンダリングされます。

次の画像は、video-overlay シーンを実行しているアプリケーションを示しています。このシーンでは、ダミーのオーバーレイアイテム(半透明のRectangle のみ)が作成され、VideoOutput アイテム上を移動します。

半透明のオーバーレイ付き動画プレーヤー

例の動作

サンプルは次の手順で実行できます:

アプリケーションの構造

Main.qml ファイルは、以下の項目を含む UI を作成します:

  • 2つのButton インスタンス。それぞれがファイル名を表示し、FileDialog を起動するために使用できます。
  • 終了用のButton 。
  • 利用可能なシーンを表示するフリック可能なリストであるSceneSelectionPanel 。
  • 左下には、QMLの再描画レートを表示する項目があります。上の数値は瞬間的なフレームレート、下の数値は過去1秒間の平均値です。

動画およびカメラモードのシーン一覧を表示するシーン選択パネル

フリック可能なリスト内の各シーンは、それぞれ独自の QML ファイルで実装されています。たとえば、video-basic シーン(画面中央に静的なVideoOutput を表示するだけのもの)は、VideoBasic.qml ファイルで実装されています。コードからもわかるように、ここではある種の継承が利用されています。VideoBasic アイテム ...

SceneBasic {
    contentType: "video"
}

...はSceneBasic 型であり...

import QtQuick
import QtQuick.Controls

Scene {
    id: root
    property string contentType
    ...
    Content {
        id: content
    ...
    }

    Label {
        anchors {
            horizontalCenter: parent.horizontalCenter
            bottom: parent.bottom
            margins: 20
        }
        text: content.started ? qsTr("Tap the screen to stop content")
                              : qsTr("Tap the screen to start content")
        z: 2.0
    }

    MouseArea {
        anchors.fill: parent
        onClicked: {
            if (content.started)
                content.stop()
            else
                content.start()
        }
    }

    Component.onCompleted: root.content = content
}

... これはScene のインスタンスであり:

import QtQuick
import QtQuick.Controls

Rectangle {
    id: root
    ...
    property QtObject content
    ...
    Button {
        id: closeButton
        anchors {
            top: parent.top
            right: parent.right
            margins: root.margins
        }
        z: 2.0
        text: qsTr("Back")
        onClicked: root.close()
    }
}

SceneBasic シーンの構造と動作を記述しますが、表示されるコンテンツの種類には依存しません。これは `Content` によって抽象化されています。

このパターンにより、特定のユースケース(この場合は単に静的なコンテンツを表示すること)を定義し、そのユースケースを動画コンテンツ(VideoBasic )とカメラコンテンツ({CameraBasic}) の両方に対してインスタンス化することが可能になります。 このアプローチは、他の多くのシーンの実装にも使用されています。例えば、「コンテンツを左から右へ、そして右から左へと繰り返しスライドさせる」という動作は、SceneMove によって実装されており、VideoMove およびCameraMove はこの に基づいています。

最上位のシーンインスタンスの contentType プロパティの値に応じて、埋め込まれたContent アイテムは、MediaPlayer アイテムまたはCamera アイテムのいずれかを作成します。

QMLの描画レートの計算と表示

QMLの描画レートは、FrequencyMonitorクラスによって計算されます。このクラスは、(notify()スロットを介して受信した)イベントのストリームを、瞬間周波数と平均周波数に変換します。

class FrequencyMonitor : public QObject
{
    Q_OBJECT
    QML_ELEMENT
    Q_PROPERTY(qreal instantaneousFrequency READ instantaneousFrequency NOTIFY
                       instantaneousFrequencyChanged)
    Q_PROPERTY(qreal averageFrequency READ averageFrequency NOTIFY averageFrequencyChanged)
    ...
public slots:
    Q_INVOKABLE void notify();
};

FrequencyMonitorクラスは、上記のようにクラス宣言にマクロQML_ELEMENT を追加することでQMLから利用可能になり、そのデータは次のようにFrequencyItemというQMLアイテムを定義することで表示されます:

import frequencymonitor

Rectangle {
    id: root
    ...
    function notify() {
        monitor.notify()
    }

    FrequencyMonitor {
        id: monitor
        onAverageFrequencyChanged: {
            averageFrequencyText.text = monitor.averageFrequency.toFixed(2)
        }
    }

    Text {
        id: labelText
        anchors {
            left: parent.left
            top: parent.top
            margins: 10
        }
        color: root.textColor
        font.pixelSize: 0.6 * root.textSize
        text: root.label
        width: root.width - 2*anchors.margins
        elide: Text.ElideRight
    }

    Text {
        id: averageFrequencyText
        anchors {
            right: parent.right
            bottom: parent.bottom
            margins: 10
        }
        color: root.textColor
        font.pixelSize: root.textSize
    }
}

結果は次のようになります:

62.5 Hzの瞬時周波数および53.15 Hzの平均周波数

あとは、QQuickView オブジェクトの afterRendering() シグナルを JavaScript 関数に接続するだけです。この関数は最終的にfrequencyItem.notify() を呼び出します:

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);
    ...
    QQuickView viewer;
    ...
    QQuickItem *rootObject = viewer.rootObject();
    ...
    QObject::connect(&viewer, SIGNAL(afterRendering()), rootObject, SLOT(qmlFramePainted()));

サンプルプロジェクト @ code.qt.io

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.