QML 미디어 플레이어 예제

QML MediaPlayer 유형을 사용하여 오디오 및 비디오 재생하기.

이 예제는 다양한 코덱을 사용하여 오디오 및 비디오 파일을 재생할 수 있는 간단한 멀티미디어 플레이어를 보여줍니다.

예제 실행하기

에서 예제를 실행하려면 Qt Creator에서 Welcome 모드를 열고 Examples 에서 예제를 선택합니다. 자세한 내용은 예제 빌드 및 실행하기를 참조하세요.

MediaPlayer 인스턴스화하기

이 예제에서 QML 코드의 진입점은 Main.qml 입니다. 여기에서 ApplicationWindow 이 생성되고 id, title, widthheight 와 같은 프로퍼티가 설정됩니다.

ApplicationWindow {
    id: root
    title: qsTr("Multimedia Player")
    width: 1280
    height: 720

다음으로 MediaPlayer 이 생성되고 비디오 및 오디오 출력을 담당하는 두 개의 프로퍼티가 정의됩니다. 첫 번째는 비디오 뷰파인더를 렌더링하는 videoOutput, 두 번째는 플레이어의 오디오 출력을 제공하는 audioOutput 입니다.

MediaPlayer {
    id: mediaPlayer
    ...
videoOutput: videoOutput
audioOutput: AudioOutput {
    id: audio
    muted: playbackController.muted
    volume: playbackController.volume
}
    ...
VideoOutput {
    id: videoOutput
    anchors.fill: parent
    visible: mediaPlayer.mediaStatus > 0

    TapHandler {
        onDoubleTapped: {
            root.fullScreen ?  root.showNormal() : root.showFullScreen()
            root.fullScreen = !root.fullScreen
        }
    }
}

VideoOutput MediaPlayer 유형의 프로퍼티는 프로퍼티가 0보다 크면 로 설정됩니다. 는 열거형이며 visible mediaStatus true mediaStatus 미디어가 설정되지 않은 경우 0과 같고 그렇지 않은 경우 0보다 큽니다. 따라서 미디어가 설정된 경우 가 표시됩니다. VideoOutput

MediaPlayer 유형에는 오류 처리를 위해 특별히 재정의할 수 있는 onErrorOccurred 이라는 신호 속성이 있습니다. 이 경우 신호는 open() 메서드를 사용하여 MessageDialog 를 열고 text 속성을 MediaPlayer 속성으로 설정합니다( errorString).

onErrorOccurred: {
    mediaError.text = mediaPlayer.errorString
    mediaError.open()
}

재생 컨트롤

사용 가능한 미디어 플레이어를 만들려면 재생을 제어하는 인터페이스가 있어야 합니다. 이는 자체 컴포넌트 파일인 PlaybackControl.qml 에서 생성되고 Main.qml 에서 인스턴스화됩니다.

PlaybackControl {
    id: playbackController
    ...
onTracksChanged: {
    audioTracksInfo.read(mediaPlayer.audioTracks)
    videoTracksInfo.read(mediaPlayer.videoTracks)
    subtitleTracksInfo.read(mediaPlayer.subtitleTracks, 6) /* QMediaMetaData::Language = 6 */
    updateMetadata()
    mediaPlayer.play()
}

생성되면 트랙 정보, 메타데이터 정보 및 MediaPlayer 객체 자체와 같은 객체가 이 유형으로 전달됩니다. PlaybackControl.qml 에서 이러한 각 객체에는 required property 이 있으므로 PlaybackControl 객체가 생성될 때 이러한 속성을 설정해야 합니다.

Item {
    id: playbackController

    required property MediaPlayer mediaPlayer
    required property MetadataInfo metadataInfo
    required property TracksInfo audioTracksInfo
    required property TracksInfo videoTracksInfo
    required property TracksInfo subtitleTracksInfo

이러한 재생 컨트롤은 섹션으로 세분화할 수 있습니다. 패널의 왼쪽 상단에는 파일 탐색기에서 파일을 선택하거나 URL을 입력하여 파일을 여는 데 사용되는 버튼 모음이 있습니다. 파일은 source 속성을 설정하여 MediaPlayer 에 로드됩니다. 두 버튼 모두 CustomButton custom component 을 사용하여 인스턴스화됩니다.

CustomButton {
    id: fileDialogButton
    icon.source: "../images/open_new.svg"
    flat: false
    onClicked: fileDialog.open()
}

CustomButton {
    id: openUrlButton
    icon.source: "../images/link.svg"
    flat: false
    onClicked: urlPopup.open()
}

이 패널에는 재생, 일시 정지, 10초 앞뒤로 탐색을 처리하는 3개의 버튼이 생성되어 중앙에 배치됩니다. 미디어는 각각 play()pause() 메서드를 사용하여 재생 및 일시 중지됩니다. 재생 또는 일시 정지 버튼을 언제 그릴지 알기 위해 playbackState 속성을 쿼리합니다. 예를 들어 열거형 값 MediaPlayer.PlayingState 과 같으면 일시 정지 버튼이 그려집니다.

CustomRoundButton {
    id: playButton
    visible: playbackController.mediaPlayer.playbackState !== MediaPlayer.PlayingState
    icon.source: "../images/play_symbol.svg"
    onClicked: playbackController.mediaPlayer.play()
}

CustomRoundButton {
    id: pauseButton
    visible: playbackController.mediaPlayer.playbackState === MediaPlayer.PlayingState
    icon.source: "../images/pause_symbol.svg"
    onClicked: playbackController.mediaPlayer.pause()
}

10초 앞뒤로 탐색하려면 MediaPlayer 유형의 position 을 10,000밀리초씩 증가시키고 setPosition() 메서드를 사용하여 설정합니다.

CustomRoundButton {
    id: forward10Button
    icon.source: "../images/forward10.svg"
    onClicked: {
        const pos = Math.min(playbackController.mediaPlayer.duration,
                           playbackController.mediaPlayer.position + 10000)
        playbackController.mediaPlayer.setPosition(pos)
    }
}

재생 찾기 및 오디오

PlaybackControl.qml 에서는 AudioControlPlaybackSeekControl 유형이 인스턴스화됩니다. 이 둘은 모두 자체 컴포넌트 파일에 정의되어 있으며 각각 볼륨 제어와 재생 찾기를 담당합니다. AudioControl 유형은 음소거 버튼과 QtQuick Controls 에서 Slider 을 정의하여 플레이어의 볼륨을 설정합니다. 이 두 속성은 mutevolume 속성을 정의하여 노출되며 Main.qmlAudioOutput 정의에서 액세스됩니다.

property alias muted: muteButton.checked
property real volume: slider.value

PlaybackSeekControlSlider 을 포함하는 RowLayout 을 사용하며 양쪽에 Text 항목이 있습니다. 두 개의 Text 항목은 재생 중인 미디어의 현재 시간과 남은 시간을 표시합니다. 이는 모두 MediaPlayer 유형의 두 가지 속성, 즉 현재 재생 위치를 밀리초 단위로 제공하는 position 과 미디어의 지속 시간을 밀리초 단위로 제공하는 duration 을 사용하여 계산됩니다.

Text {
    id: currentTime
    Layout.preferredWidth: 45
    text: seekController.formatToMinutes(seekController.mediaPlayer.position)
    horizontalAlignment: Text.AlignLeft
    font.pixelSize: 11
}
    ...
Text {
    id: remainingTime
    Layout.preferredWidth: 45
    text: seekController.formatToMinutes(seekController.mediaPlayer.duration - seekController.mediaPlayer.position)
    horizontalAlignment: Text.AlignRight
    font.pixelSize: 11
}

Slider 유형은 미디어 플레이어가 라이브 미디어가 아닌 검색 가능한 미디어인 경우에만 활성화됩니다. MediaPlayer 유형에는 seekable 이라는 속성이 있습니다. SlidervaluepositiondurationMediaPlayer 속성을 사용하여 계산됩니다.

enabled: seekController.mediaPlayer.seekable
value: seekController.mediaPlayer.position / seekController.mediaPlayer.duration

메타데이터 및 트랙 정보

PlaybackControl 유형은 현재 로드된 미디어 및 트랙 선택의 메타데이터와 재생 속도를 업데이트하는 기능에 대한 정보를 포함하는 SettingsPopup 을 인스턴스화합니다. 이 PopupSettingsPopup.qml 에 정의되어 있습니다.

메타데이터는 자체 컴포넌트 파일인 MetadataInfo.qml 에 포함되어 있으며, ListModel, 지우는 함수 clear(), 채우는 함수 read(MediaMetadata metadata) 를 포함합니다. read(MediaMetadata metadata) 함수는 MediaMetaData 유형의 객체를 매개변수로 받고 키-값 구조를 탐색하여 ListViewmodel 로 데이터를 추출합니다. 이를 위해 사용되는 메서드는 MediaMetaData 의 모든 키를 반환하는 keys() 와 주어진 key 에 대해 value 을 반환하는 {stringValue(키 키)}입니다.

function read(metadata) {
    if (!metadata)
        return
    for (const key of metadata.keys())
        if (metadata.stringValue(key))
            listModel.append({
                                name: metadata.metaDataKeyToString(key),
                                value: metadata.stringValue(key)
                            })
}

ListModel {
    id: listModel
}

그러면 데이터는 ListView 유형으로 SettingsPopup.qml 에 표시됩니다. 이 ListViewdelegateMediaMetaData 항목에서 추상화된 키-값 쌍에 해당하는 두 개의 Text 항목으로 이루어진 행입니다.

Popup 의 다른 쪽에는 오디오, 비디오 및 자막에 대한 재생 속도 제어 및 트랙 선택이 있습니다. 재생 속도는 ComboBox 에서 선택되고 playbackRate 속성을 사용하여 설정됩니다.

settingsController.mediaPlayer.playbackRate = (currentIndex + 1) * 0.25

TracksInfo.qml 에 정의된 TracksInfo 라는 유형은 트랙에 대한 데이터를 포함합니다. 보다 구체적으로, ListModel 에는 트랙의 제목, 특히 자막의 경우 언어가 포함됩니다. 이 정보는 TracksInfo 유형에 정의된 read(MediaMetadata mediaMetadata) 함수를 호출하여 Main.qml 에 채워집니다.

onTracksChanged: {
    audioTracksInfo.read(mediaPlayer.audioTracks)
    videoTracksInfo.read(mediaPlayer.videoTracks)
    subtitleTracksInfo.read(mediaPlayer.subtitleTracks, 6) /* QMediaMetaData::Language = 6 */
    updateMetadata()
    mediaPlayer.play()
}

그런 다음 TracksInfo 에 정의된 modelComboBox에 있는 SettingsPopup 에서 쿼리하여 현재 트랙을 선택합니다.

settingsController.mediaPlayer.pause()
tracksInfo.selectedTrack = currentIndex
settingsController.mediaPlayer.play()

예제 프로젝트 @ code.qt.io

© 2025 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.