QML 组件 'Video' 无法播放来自 Qt 资源文件的视频文件

QML Component 'Video' can not play video files from Qt resource files

整个项目可以在这里找到:

QML Video Test Project

我制作了一个示例应用程序,其中包含三个按钮、一个图像和一个视频播放器。按下按钮时应该播放视频。这就是按钮的区别:

  1. 访问与应用程序可执行文件位于同一文件夹中的视频文件。
  2. 访问添加到 Qt 资源文件的视频文件。
  3. 从没有压缩的外部二进制 Qt 资源文件访问视频文件。

只有按钮 1. 在我的应用程序中起作用,post 的原因是我 运行 不明白为什么按钮 2. 和 3. 不能播放视频。

应用程序中包含的图像是与视频文件一起打包在外部二进制Qt 资源文件中的图像。成功从外部资源文件中读取此图像。这意味着访问外部资源文件不是问题。

这是 main.qml 文件:

import QtQuick 2.4
import QtQuick.Window 2.2
import com.qml.externalresourcemanager 1.0
import QtMultimedia 5.4
import QtQuick.Controls 1.2

Window {
    visible: true

    minimumHeight: 700
    minimumWidth: 400

    property string imageSelected: ""
    property string videoSelected: ""

    ExternalResourceManager {
        id: externalResourceManager

        Component.onCompleted: {
            console.log("External resource registered: " + registerExternalResource("file:/../../VideoTest/binaryExpansionFile.rcc"))
            imageSelected = "externalImage.jpg"
        }
    }

    Button {
        id: button0
        width: parent.width
        height: parent.height / 7
        anchors.top: parent.top
        text: "Click me to play as local file"
        onClicked: {
            console.log(installPath + "local.mp4")
            videoSelected = installPath + "local.mp4"
        }
    }

    Button {
        id: button1
        width: parent.width
        height: parent.height / 7
        anchors.top: button0.bottom
        text: "Click me to play local resource file"
        onClicked: {
            videoSelected = "local.mp4"
        }
    }

    Button {
        id: button2
        width: parent.width
        height: parent.height / 7
        anchors.top: button1.bottom
        text: "Click me to play external resource file"
        onClicked: {
            videoSelected = "external.mp4"
        }
    }

    Image {
        id: image
        source: imageSelected
        width: parent.width
        height: parent.height * 2 / 7
        anchors.top: button2.bottom
    }

    Video {
        id: video
        source: videoSelected
        height: parent.height * 2 / 7
        width: parent.width
        anchors.top: image.bottom
        fillMode: VideoOutput.PreserveAspectFit

        onStatusChanged: {
            var temp

            switch (playbackState)
            {
                case MediaPlayer.NoMedia:
                    temp = "MediaPlayer.NoMedia"
                break;

                case MediaPlayer.Loading:
                    temp = "MediaPlayer.Loading"
                break;

                case MediaPlayer.Loaded:
                    temp = "MediaPlayer.Loaded"
                break;

                case MediaPlayer.Buffering:
                    temp = "MediaPlayer.Buffering"
                break;

                case MediaPlayer.Stalled:
                    temp = "MediaPlayer.Stalled"
                break;

                case MediaPlayer.Buffered:
                    temp = "MediaPlayer.Buffered"
                break;

                case MediaPlayer.EndOfMedia:
                    temp = "MediaPlayer.EndOfMedia"
                break;

                case MediaPlayer.InvalidMedia:
                    temp = "MediaPlayer.InvalidMedia"
                break;

                case MediaPlayer.UnknownStatus:
                    temp = "MediaPlayer.UnknownStatus"
                break;
            }

            console.log(temp)

            if (status === MediaPlayer.Loaded)
            {
                video.play()
            }
        }
        onBufferProgressChanged: {
            console.log("Buffering: " + bufferProgress * 100)
        }
        onSourceChanged: {
            console.log("Source: " + source)
        }
        onAvailabilityChanged: {
            console.log("Availability: " + availability)
        }
        onErrorChanged: {
            console.log("Error: " + error)
        }
        onErrorStringChanged: {
            console.log("Error String: " + errorString.toString())
        }
        onHasVideoChanged: {
            console.log("Has video: " + hasVideo)
        }
        onPlaybackStateChanged: {
            var temp

            switch (playbackState)
            {
                case MediaPlayer.PlayingState:
                    temp = "MediaPlayer.PlayingState"
                break;

                case MediaPlayer.PausedState:
                    temp = "MediaPlayer.PausedState"
                break;

                case MediaPlayer.StoppedState:
                    temp = "MediaPlayer.StoppedState"
                break;
            }

            console.log(temp)
        }
    }
}

按下按钮 1 我的应用程序输出:

Resource path:  "file:/../../VideoTest/binaryExpansionFile.rcc"
qml: External resource registered: true
qml: file:/C:/Users/MisterX/Documents/QtProjects/build-VideoTest-Desktop_Qt_5_4_2_MinGW_32bit-Debug/debug/local.mp4
qml: Source: file:///C:/Users/MisterX/Documents/QtProjects/build-VideoTest-Desktop_Qt_5_4_2_MinGW_32bit-Debug/debug/local.mp4
qml: MediaPlayer.UnknownStatus
qml: Has video: true
qml: MediaPlayer.UnknownStatus
qml: MediaPlayer.NoMedia
qml: MediaPlayer.PlayingState

按下按钮 2 我的应用程序输出:

Resource path:  "file:/../../VideoTest/binaryExpansionFile.rcc"
qml: External resource registered: true
qml: Source: qrc:/local.mp4
qml: MediaPlayer.UnknownStatus
qml: Has video: false
qml: MediaPlayer.UnknownStatus
qml: MediaPlayer.NoMedia
qml: MediaPlayer.PlayingState

整个项目可以在这里找到: QML Video Test Project

这是使用 DirectShow 后端的 MinGW 编译器时的错误。有关详细信息,请参阅此 bug report link