关于Qt视频文件无法播放的问题

如下代码所示,将MP4格式的视频文件添加到资源文件中后,代码中使用资源文件的相对路径无法播放视频,但是使用绝对路径(没有放入资源文件中)就可以正常播放,什么原因呢,以及解决方法是什么?

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    QVideoWidget * videoWin = new QVideoWidget(this);
    videoWin->resize(400,300);
    QMediaPlayer * player = new QMediaPlayer(this);
    player->setVideoOutput(videoWin);

//视频使用绝对路径可以播放
//    player->setMedia(QMediaContent(QUrl::fromLocalFile("D:/QtTest1/test.mp4")));
    player->setMedia(QMediaContent(QUrl::fromLocalFile(":/res/test.mp4")));
    player->play();
}

Qt的媒体组件应该都没有做资源文件的特殊处理,而媒体组件最终都是调用外部库进行播放,外部库从资源地址是无法读取文件内容的
可以尝试使用QFile先读取文件,然后将QFile作为QIODevice传入setMedia的stream参数

出现这个问题的原因是使用资源文件中的相对路径时,QUrl::fromLocalFile()方法不能正确地解析路径,因为资源文件中的路径不是文件系统中的路径,而是在二进制文件中的路径。

解决方法是使用QUrl::fromUserInput()方法来解析路径,这个方法可以接受相对路径和绝对路径,并返回一个正确的QUrl对象。修改代码如下:

Widget::Widget(QWidget *parent)
: QWidget(parent)
{
QVideoWidget * videoWin = new QVideoWidget(this);
videoWin->resize(400,300);
QMediaPlayer * player = new QMediaPlayer(this);
player->setVideoOutput(videoWin);

//修改为使用fromUserInput()方法来解析路径
player->setMedia(QMediaContent(QUrl::fromUserInput(":/res/test.mp4")));
player->play();
}

作者可以尝试一下修改的代码

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 这有个类似的问题, 你可以参考下: https://ask.csdn.net/questions/7497427
  • 这篇博客你也可以参考下:Qt描述路径Qfile时绝对路径不明错误
  • 这篇博客也不错, 你可以看下Qt描述路径Qfile时绝对路径不明错误
  • 除此之外, 这篇博客: 解决QT接受串口数据时数据更新不及时,串口数据太多导致程序界面崩溃,串口接收数据过快等问题中的 4) 运行错误,报错 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:

    上述解决完后,又发现一个新的问题,也不知道时软件的缘故还是程序不对,read和readAll函数一次能够接受的最大数据为32个字节。尝试使用64位编译器,在程序中再加一个读串口的程序都没有作用,加的第二次读串口的程序根本就没有进去。由于每次接受32个字节,每次都是循环到需要的报文处截止,这就导致有效的数据可能出现在第二次接受的数据中,但是由于不是报文头,程序给剔除掉了。导致每次输出的数据越来越少,到最后程序报错:
    在这里插入图片描述
    于是查阅可不可以读取串口的时候读取两次,结果又发现了一个很神奇的函数bytesAvailable(),通过这个函数,我们为您可以在缓存中的数据达到大于等于33字节的时候再进行读取操作,同时保留补充的字节的语句,终于大功告成了!代码如下:

       if(portAngle.bytesAvailable()>=33){  // 等数据达到要求再进行读取操作
            buffer.append(portAngle.read(33));
            while(!buffer.isEmpty() and !(buffer[0]==0x55 and buffer[1]==0x53)){// 对错误数据进行处理,直到满足要求
                buffer.remove(0,1);
            }
            if (buffer!=""){
                buffer.append(portAngle.read(11-buffer.size())); //补充数据,保证所需字段数据完整
                ucRxBuffer = reinterpret_cast<unsigned char *>(buffer.data());
                angleHandle(ucRxBuffer);
                // 清空缓冲区
                buffer.clear();
            }
        }
    

    后续遇到问题,在更新······


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^