QML メディアプレーヤーの例

QMLMediaPlayer タイプを使ったオーディオやビデオの再生。

この例題では、様々なコーデックを使ってオーディオファイルやビデオファイルを再生できる、シンプルなマルチメディアプレーヤーを示します。

例の実行

Qt Creator からサンプルを実行するには、Welcome モードを開き、Examples からサンプルを選択します。詳細については、Building and Running an Example を参照してください。

MediaPlayerのインスタンス化

この例の QML コードのエントリーポイントはMain.qml です。ここでApplicationWindow が作成され、idtitlewidthheight などのプロパティが設定されます。

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

次に、MediaPlayer が作成され、映像と音声の出力を担当する2つのプロパティが定義されます。まず、ビデオ・ビューファインダーをレンダリングする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 型のvisible プロパティは、MediaPlayer 型のmediaStatus プロパティが 0 より大きいとき、true に設定される。mediaStatus は列挙型で、No media が設定されているときは 0 に等しく、そうでないときは 0 より大きい。したがって、VideoOutput は、メディアが設定されているときに表示される。

MediaPlayer 型にはonErrorOccurred というシグナル・プロパティがあり、エラー処理専用にオーバーライドできます。この場合、シグナルはopen() メソッドを使用してMessageDialog を開き、そのtext プロパティをerrorString というMediaPlayer プロパティに設定します。

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 propertyPlaybackControl オブジェクトが作成されるときに、これらのプロパティを設定しなければならないことを意味する。

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()
}

3つのボタンが作成され、このパネルの中央に配置され、再生、一時停止、10秒前後のシークを処理します。メディアの再生と一時停止は、それぞれ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秒前または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

PlaybackSeekControl は、Slider を含むRowLayout を使用し、その両側にText の項目があります。2つの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 というプロパティがあります。Slidervalue は、MediaPlayerpositionduration プロパティを使用して計算されます。

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

メタデータとトラック情報

PlaybackControl タイプはSettingsPopup をインスタンス化する。このインスタンスには、現在ロードされているメディアのメタデータとトラック選択に関する情報、および再生レートを更新する機能が含まれる。このPopup は、SettingsPopup.qml で定義されている。

メタデータは、独自のコンポーネント・ファイルであるMetadataInfo.qml に含まれている。このファイルには、ListModel 、それをクリアする関数clear() 、それを入力する関数read(MediaMetadata metadata) が含まれている。read(MediaMetadata metadata) 関数は、MediaMetaData 型のオブジェクトをパラメー タとして受け取り、そのキー・バリュー構造をナビゲートして、ListViewmodel にデータを抽出する。このために使用されるメソッドは、MediaMetaData のすべてのキーを返すkeys() と、指定されたkeyvalue を返す {stringValue(Key key)} である。

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
}

そして、データはSettingsPopup.qmlListView 型で表示される。このListViewdelegate は、MediaMetaData 項目から抽象化されたキーと値のペアに対応する、2つの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 で定義されたmodel が、SettingsPopupComboBoxes で照会され、現在のトラックが選択される。

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

プロジェクト例 @ code.qt.io

©2024 The Qt Company Ltd. 本書に含まれる文書の著作権は、それぞれの所有者に帰属します。 本書で提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。