我需要播放一个自定义 AVI 文件,其中包含一个经典视频流、一个音频流还有一个自定义数据流。
自定义流包含由一些自定义小部件可视化的数据;这些小部件只需要在适当的时间将每个自定义框架写入缓冲区。
我们的应用是基于 Qt 的,已经使用 QMediaPlayer
/QVideoWidget
来播放传统视频,但是额外的自定义流让事情变得更加复杂,因为 AFAIK QMediaPlayer
只播放视频/音频而忽略其他所有内容。
我想避免重新发明整个 qt-multimedia
,但我不确定如何充分利用可用的 Qt 类。
到目前为止我的想法是:
编写一个自定义媒体播放器类,使用
ffmpeg
对视频进行解复用和解码,实现计时,使用QAudioOutput
进行播放音频,生成QVideoFrame
流以在视频上播放并将自定义数据写入某个缓冲区以进行可视化。问题:为了避免编写代码来重新缩放/转换视频帧,我想重用
QVideoWidget
,但它似乎只适用于“真实的”QMediaPlayer
.对输入文件进行解复用,并为
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同步:
尝试使用一些计时器线程(Thread 和 timer 的组合)。制作一个使用 MyVideoAudioStream(使用时间作为索引中的变量)和“Mycustomreader”(使用时间作为索引中的变量的数据包数组)的任何流索引作为主体的流索引。在 QMediaPlayer 中添加一些循环遍历位置(@param:time)的逻辑。由此,您可以同时解析两者的执行代码。随着时间的增加,QMediaPlayer 中的位置和流的索引会增加。
如果您的自定义流中没有索引或位置,我强烈建议您创建一个。
关于c++ - 使用 QtMultimedia 播放自定义 avi 数据流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30005349/