我彻底搜索以找到我的问题的答案,但到目前为止没有其他帖子有帮助。 我正在 Qt 中开发一个应用程序,我需要在其中播放通过自定义协议(protocol)接收的视频流。我发现自己尝试以各种可能的方式在 QMediaPlayer 中提供这些数据包,但没有成功。我的想法是在 QBuffer 中写入传入的数据包,然后从 QMediaPlayer 中读取它们。按照我的试验:
/// VideoPlayer.h
class VideoPlayer : public QWidget
{
public slots:
void play();
void handlePacket(QByteArray);
[...]
private:
QMediaPlayer mediaPlayer;
QBuffer buffer;
};
/// VideoPlayer.cpp
VideoPlayer::VideoPlayer(QWidget *parent)
: QWidget(parent)
, mediaPlayer(0, (QMediaPlayer::StreamPlayback))
{
buffer.open(QBuffer::ReadWrite);
}
void VideoPlayer::handlePacket(QByteArray packet)
{
buffer.buffer().append(packet);
}
void VideoPlayer::play()
{
mediaPlayer.setMedia(QMediaContent(), &buffer);
mediaPlayer.play();
}
使用上述 QMediaPlayer 在调用 mediaPlayer.setMedia(QMediaContent(), &buffer)
时播放缓冲区中的数据,但似乎忽略了新数据包已附加到缓冲区。可能是因为我正在直接访问内部 QByteArray(我检查了 QIODevice::readyRead 信号是否发出并且确实如此)?除了再次调用 setMedia 之外,我找不到让 QMediaPlayer 播放新传入数据的方法。有没有办法通知 QMediaPlayer 媒体长度已更改?
有没有更简单的方法来做这个?我考虑过编写自己的 QIODevice 或以某种方式将我的数据包接收器集成到 Qt 框架中以提供我的自定义流作为 QMediaContent?
是否有任何其他库或方法可以让我完成这项任务?
我正在使用 Qt 5.4。 预先感谢您的帮助。
最佳答案
我的回答不是真正的回答,只是分享我的经验和研究结果。这侧重于流的音频部分。
我目前正在处理类似的问题。我有一个自定义协议(protocol),它在一个传入的 [from network] 数据帧中包含一个编码图像和一个编码音频部分。我需要分别处理图像和音频:
- 解码图像并将原始 RGB 数据发送到另一个将显示它的进程(大声笑没关系)
- 以任何方式播放音频部分
主要:我只能使用Qt库。这是因为 libVLC [我现在用于这些事情] 缓冲音频/视频,我没有找到任何方法来禁用它并实时播放流。我应该注意到传入的流来自摄像机,因此我需要尽可能实时地播放它。
在我的快速研究中,我找到了一种播放东西的方法:
// init method
{
// ...
mPlayer = new QMediaPlayer(this, QMediaPlayer::StreamPlayback);
mBuffer = new QBuffer(this);
mBuffer->open(QIODevice::ReadWrite);
// ...
}
// trying to play audio portion
void MyCoolPlayer::handleFrameAudio(const QByteArray &audioBlob)
{
mBuffer->seek(0);
mBuffer->write(audioBlob);
mBuffer->seek(0);
mPlayer->setMedia(QMediaContent(), mBuffer);
mPlayer->play();
}
这播放了一些失真的声音,但至少它播放了一些东西。
此外,如果您有一些音频/视频解码器,您可以使用:
- QPainter::drawImage 在空部件上绘制解码后的 rgb 图像数据
- QAudioOutput 播放解码后的 pcm 音频数据
关于c++ - 使用 QMediaPlayer 播放自定义流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30828567/