C++ 使用QMediaPlayer播放自定义流

C++ 使用QMediaPlayer播放自定义流,c++,qt,C++,Qt,我仔细搜索了一下,想找到问题的答案,但到目前为止,没有其他帖子对我有所帮助。 我正在Qt中开发一个应用程序,其中需要播放通过自定义协议接收的视频流。我发现自己尝试了各种可能的方法在QMediaPlayer中为这些数据包提供数据,但没有成功。我的想法是在QBuffer中写入传入的数据包,然后从QMediaPlayer读取它们。在我的审判之后: /// VideoPlayer.h class VideoPlayer : public QWidget { public slots: void

我仔细搜索了一下,想找到问题的答案,但到目前为止,没有其他帖子对我有所帮助。 我正在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

是否有其他库或方法可以让我完成此任务

我正在使用Qt5.4。
提前感谢您的帮助。

我想这是同样的问题。读一下。但是另一个用户也没有在
Qt
中找到解决方案,他也需要使用
VLC
库。

我的答案不是真正的答案,只是分享我的经验和研究结果。这主要集中在流的音频部分。

我目前正在处理类似的问题。我有一个自定义协议,在一个传入的[来自网络]数据帧中包含一个编码图像和一个编码音频部分。我需要分别处理图像和音频:

  • 解码图像并将原始RGB数据发送到另一个进程,该进程将显示图像(lol nevermind)
  • 以任何方式播放音频部分
Main:我只能使用Qt库。这是因为libVLC(我现在用它来做这些事情)缓冲音频/视频,我没有找到任何方法来禁用它并实时播放流。我应该注意到,传入的流来自摄像机,所以我需要尽可能实时地播放它

在我的快速研究中,我发现了一种玩东西的方法:

这会播放一些失真的声音,但至少会播放一些东西

此外,如果您有一些音频/视频解码器,您可以使用:

  • QPaint::drawImage可在空小部件上绘制解码的rgb图像数据
  • QAudioOutput播放解码的pcm音频数据

我在创建使用QT/QML播放视频流的POC时遇到了同样的问题。对我来说,QBuffer也不起作用。在播放过程中,我还尝试将视频文件的块附加到另一个线程的缓冲区中。QMediaPlayer仅播放第一个区块并停止。我假设这不是模拟流的正确方法

以下是两种行之有效的方法

< > >用C++的qMIIAPLAPER播放QML视频输出,使用<代码> SETMIVE(QURL)http://127.0.0.1:8080"));流由VLC media player使用HTTP创建到8080端口

  • 我还通过将VLC media player创建的流传递给QMediaPlayer,成功地将其播放到本地文件
    setMedia(QMediaContent(),&localFile)


  • 您可以提供有关正在播放的媒体类型的更多信息(容器/原始RTP或UDP/…)。我的猜测是,由于各种格式都有数据包边界,可能您跳过了一些告诉媒体播放器新数据可用的数据?无论如何,子类化QIODevice听起来是一个不错的方法。
    // 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();
    }