我彻底搜索了我的问题的答案,但到目前为止还没有其他帖子有用。 我正在Qt中开发一个应用程序,我需要播放通过自定义协议接收的视频流。我发现自己试图以各种可能的方式在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。 在此先感谢您的帮助。
答案 0 :(得分:1)
我的答案不是真正的答案,只是分享我的经验和研究成果。这专注于流的音频部分。
我目前正在处理同样的问题。我有自定义协议,其中包含一个传入[来自网络]数据帧中的一个编码图像和一个编码音频部分。我需要分别处理图像和音频:
主要:我只能使用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();
}
这会播放一些扭曲的声音,但至少它起到了一些作用。
此外,如果你有一些音频/视频解码器,你可以使用:
答案 1 :(得分:0)
我认为this是同一个问题。阅读。但是其他用户也没有在Qt
中找到他需要使用VLC
库的解决方案。
答案 2 :(得分:0)
在创建使用QT / QML播放视频流的POC期间,我遇到了相同的问题。对我来说,它也不适用于QBuffer。在播放过程中,我还尝试将视频文件的块从另一个线程追加到缓冲区。 QMediaPlayer仅播放第一个块并停止。我认为这不是模拟流的正确方法。
这是两种有效的方法
使用setMedia(QUrl("http://127.0.0.1:8080"));
使用C ++ QMediaPlayer在QML VideoOutput中播放流。该流是由VLC媒体播放器使用HTTP到8080端口创建的。
我还成功地将VLC媒体播放器创建的流通过以下方式传递到本地文件:
setMedia(QMediaContent(), &localFile);
。