使用QtMultedia播放自定义avi数据流

Playing a custom avi data stream using QtMultimedia

本文关键字:avi 数据流 自定义 播放 QtMultedia 使用      更新时间:2023-10-16

我需要播放一个自定义AVI文件,该文件包含经典视频流、音频流以及自定义数据流。

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

我们的应用程序是基于Qt的,并且已经使用QMediaPlayer/QVideoWidget来播放传统视频,但额外的自定义流使事情变得更加复杂,因为AFAIKQMediaPlayer只播放视频/音频,而忽略其他一切。

我希望避免重新设计整个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同步,正确处理标头和元数据。


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

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

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

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

看起来Qt实际上已经在某种程度上支持了数据流的概念-http://doc.qt.io/qt-5/qmediastreamscontrol.html#details显示它是qmediastreamscontrol的可选流类型之一。

其他文件包括http://doc.qt.io/qt-5/qmediaserviceproviderplugin.html建议您可以创建一个实现视频和音频QMediaControl接口的QMediaServiceProviderPlugin(可能通过对现有媒体服务提供商进行子类化),也可以创建自己的QMediaControl接口子类来创建一个Control来处理原始数据。

希望以这种方式实现将允许您使用现有的设施来拆分流、处理头和类似的功能。

不幸的是,构建QMediaService的细节似乎"超出了本文档的范围,应该寻求相关邮件列表或IRC渠道的支持。"(http://doc.qt.io/qt-5/qmediaservice.html#details)。来源(http://code.qt.io/cgit/qt/qtmultimedia.git/tree/src/multimedia)然而,除了http://code.qt.io/cgit/qt/qtmultimedia.git/tree/src/plugins,其中包括directshow/gstreamer/coreaudio插件。

在任何情况下,我都会尝试子类化并尽可能少地重新实现