QML 组件“视频”无法播放 Qt 资源文件中的视频文件

Posted

技术标签:

【中文标题】QML 组件“视频”无法播放 Qt 资源文件中的视频文件【英文标题】:QML Component 'Video' can not play video files from Qt resource files 【发布时间】:2015-06-22 21:49:12 【问题描述】:

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

QML Video Test Project

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

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

只有按钮 1. 在我的应用程序中工作,而这篇文章的原因是我不知道为什么按钮 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

【问题讨论】:

doc.qt.io/qt-5/qml-url.html 说你的 URL 应该是 qrc:///local.mp4。我怀疑不是这样...... 不是。我已经阅读并尝试过,但是很好:) 可能是一个错误。你使用 Qt 5.4.2 吗?您可以尝试 5.5 beta 或 5.5 RC 快照。我查看了 bugreports.qt.io 并没有发现任何明显的东西。 5.4.2 是的。我试试 5.5 RC @HamishMoffatt:也不适用于 5.5 RC =/ 有什么建议吗? 【参考方案1】:

这是使用使用 DirectShow 后端的 MinGW 编译器时的错误。请参阅此bug report link 了解更多信息。

【讨论】:

以上是关于QML 组件“视频”无法播放 Qt 资源文件中的视频文件的主要内容,如果未能解决你的问题,请参考以下文章

Qt Quick 多媒体 - 播放音乐和视频

Qt on android 播放视频的实现

如何在 QML 中播放目录中的视频

如何使用 video 5.12 qt qml 播放视频?

当我尝试播放不在 qrc 中的媒体文件时,出现错误“尝试播放无效的 Qt 资源”

QML MediaPlayer ServiceMissing异常解决办法