c++ - 使用 QtMultimedia 播放自定义 avi 数据流

标签 c++ qt ffmpeg qtmultimedia

我需要播放一个自定义 AVI 文件,其中包含一个经典视频流、一个音频流还有一个自定义数据流

自定义流包含由一些自定义小部件可视化的数据;这些小部件只需要在适当的时间将每个自定义框架写入缓冲区。

我们的应用是基于 Qt 的,已经使用 QMediaPlayer/QVideoWidget 来播放传统视频,但是额外的自定义流让事情变得更加复杂,因为 AFAIK QMediaPlayer 只播放视频/音频而忽略其他所有内容。

我想避免重新发明整个 qt-multimedia,但我不确定如何充分利用可用的 Qt 类。


到目前为止我的想法是:

  1. 编写一个自定义媒体播放器类,使用 ffmpeg 对视频进行解复用和解码,实现计时,使用 QAudioOutput 进行播放音频,生成 QVideoFrame 流以在视频上播放并将自定义数据写入某个缓冲区以进行可视化。

    问题:为了避免编写代码来重新缩放/转换视频帧,我想重用 QVideoWidget,但它似乎只适用于“真实的”QMediaPlayer.

  2. 对输入文件进行解复用,并为 QMediaPlayer 提供 AV 流。 使用 ffmpeg 对输入进行解复用(可能将解码留给 Qt 后端),让一个 QIODevice 仅从输入文件中检索视频/音频流,另一个用于检索数据流。使用 QMediaPlayer 播放视频/音频。

                  +-------+                          
                  | QFile |                          
                  +---^---+                          
                      |                              
                   inherits                          
                      |                              
            +--------------------+
            |    MyAviDemuxer    |
            |                    |
            |  holds a queue of  |
            |  demuxed packets   |
            +--------------------+
            |                    |
      readDataPacket      readVideoPacket
            |                    |
    +-------v--------+  +--------v-----------+            +-----------+
    | MyCustomReader |  | MyVideoAudioStream +--inherits--> QIODevice |
    +----------------+  +--------+-----------+            +-----------+
                                 |       
                              setMedia                  
                                 |                  
                         +-------v-------+           
                         | QMediaPlayer  |           
                         +---------------+           
    

    问题:将数据流的时序与QMediaPlayer同步,正确处理headers和metadata。


我稍微倾向于选项 1,只是因为它给了我更多的控制权,但我想知道我是否错过了一个更简单的解决方案(甚至仅限 Windows)。

最佳答案

我知道你有相当定制的类结构,但也许你可以从编码新手那里得到一些建议。 我认为您应该将一些更基本的现有数据类型与您的自定义类一起使用。

解决方案:将数据流的时序与QMediaPlayer同步:
尝试使用一些计时器线程(Threadtimer 的组合)。制作一个使用 MyVideoAudioStream(使用时间作为索引中的变量)和“Mycustomreader”(使用时间作为索引中的变量的数据包数组)的任何流索引作为主体的流索引。在 QMediaPlayer 中添加一些循环遍历位置(@param:time)的逻辑。由此,您可以同时解析两者的执行代码。随着时间的增加,QMediaPlayer 中的位置和流的索引会增加。

如果您的自定义流中没有索引或位置,我强烈建议您创建一个。

关于c++ - 使用 QtMultimedia 播放自定义 avi 数据流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30005349/

相关文章:

android - 为 Qt 项目的多个架构生成一个 APK

video - ffmpeg:两步编码是否解决了视频转换过程中的问题?

python - 子进程中单引号和双引号之间的区别[Python 3.4]

c++ - 如何在 OpenGL 中绘制立方体?

c# - 开关盒编程实践

c++ - 后台程序接收大量控制台输入,而监控程序在前台运行

c++ - Qt Creator 中缺少编译器

c++ - 如何在 Qt Creator 中添加可调整大小的小部件?

video - ffmpeg 将 mov 文件转换为 mp4 用于 HTML5 视频标签 IE9

c++ - 创建中间件以使相机兼容 ONVIF