이 페이지에서

QML 비디오 예제

비디오 및 카메라 뷰파인더 콘텐츠 변환.

QML 비디오 예 제는 QML VideoOutput 및 Camera 유형에 적용할 수 있는 다양한 변환(이동, 크기 조정, 회전, 종횡비 변경)을 보여줍니다.

또한 네이티브 코드를 QML과 결합하여 더 고급 기능을 구현하는 방법도 보여줍니다. 이 예제에서는 C++ 코드를 사용하여 QML 프레임 속도를 계산합니다. 이 값은 비디오 콘텐츠 위에 오버레이된 반투명 항목을 통해 QML로 렌더링됩니다.

다음 이미지는 비디오 오버레이 장면을 실행 중인 애플리케이션을 보여줍니다. 이 장면은 VideoOutput 항목을 가로질러 이동하는 더미 오버레이 항목(단순히 반투명한 Rectangle)을 생성합니다.

반투명 오버레이가 적용된 동영상 플레이어

예제 실행

다음 경로에서 예제를 실행할 수 있습니다.

애플리케이션 구조

Main.qml 파일은 다음 항목을 포함하는 UI를 생성합니다:

  • 두 개의 Button 인스턴스로, 각각 파일 이름을 표시하며 FileDialog 을 시작하는 데 사용할 수 있습니다.
  • 종료용 Button.
  • 사용 가능한 장면을 표시하는 플릭 가능한 목록인 SceneSelectionPanel.
  • 왼쪽 하단에는 QML 재그리기 빈도를 표시하는 항목이 있습니다. 위쪽 숫자는 순간 프레임 속도이고, 아래쪽 숫자는 지난 1초 동안의 평균 프레임 속도입니다.

동영상 및 카메라 모드 장면 목록이 표시된 장면 선택 패널

플릭커블 목록에 있는 각 장면은 별도의 QML 파일로 구현됩니다. 예를 들어, 비디오-기본 장면(화면 중앙에 정적인 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.