在上一篇报告中,我们已经可以将RTSP转成RTMP进行直播了,这次我们要将HDMI输入也要转成RTMP进行直播。
我们需要在上一篇的基础上再增加一个HDMI直播按钮。
头文件
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QProcess>
#include <stdlib.h>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_pushButton_clicked();
void onReadyReadStandardOutput();
void onReadyReadStandardError();
void on_pushButton_2_clicked();
void on_pushButton_3_clicked();
private:
Ui::MainWindow *ui;
QProcess *ffmpegProcess;
char rtsp_link[255], rtmp_link[255];
};
#endif
源文件
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
ffmpegProcess = new QProcess(this);
ffmpegProcess->setProcessChannelMode(QProcess::MergedChannels);
connect(ffmpegProcess, &QProcess::readyReadStandardOutput, this, &MainWindow::onReadyReadStandardOutput);
connect(ffmpegProcess, &QProcess::readyReadStandardError, this, &MainWindow::onReadyReadStandardError);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::onReadyReadStandardOutput()
{
QByteArray output = ffmpegProcess->readAllStandardOutput();
ui->label_status->setText(QString("Status: Output - ") + QString(output));
}
void MainWindow::onReadyReadStandardError()
{
QByteArray error = ffmpegProcess->readAllStandardError();
ui->label_status->setText(QString("Status: Error - ") + QString(error));
}
void MainWindow::on_pushButton_clicked()
{
if (ui->lineEdit_rtsp->text().length() == 0) {
ui->label_status->setText("Status: Error - rtsp link is empty");
return;
}
if (ui->lineEdit_rtmp->text().length() == 0) {
ui->label_status->setText("Status: Error - rtmp link is empty");
return;
}
strcpy(rtsp_link, ui->lineEdit_rtsp->text().toStdString().c_str());
strcpy(rtmp_link, ui->lineEdit_rtmp->text().toStdString().c_str());
QString program = "ffmpeg";
QStringList arguments;
arguments << "-i" << rtsp_link << "-vcodec" << "h264_rkmpp" << "-an" << "-f" << "flv" << rtmp_link;
ffmpegProcess->start(program, arguments);
}
void MainWindow::on_pushButton_2_clicked()
{
ffmpegProcess->write("q");
}
void MainWindow::on_pushButton_3_clicked()
{
if (ui->lineEdit_rtmp->text().length() == 0) {
ui->label_status->setText("Status: Error - rtmp link is empty");
return;
}
strcpy(rtmp_link, ui->lineEdit_rtmp->text().toStdString().c_str());
QString program = "ffmpeg";
QStringList arguments;
arguments << "-f" << "v4l2" << "-pixel_format" << "nv12" << "-i" << "/dev/video73" << "-vcodec" << "h264_rkmpp" << "-an" << "-f" << "flv" << rtmp_link;
ffmpegProcess->start(program, arguments);
}
这次依旧是将MainWindow类粘贴上来,其他基本都可以不变,代码的使用可以看上篇报告,ffmpeg命令可以查看第二篇报告,代码的全部内容以附件形式附上来。
*附件:test.zip
这里需要有一些说明的是,在我们查看HDMI输入支持的pixel format的时候可以看到除了RGB格式,有3个NV格式,在第2篇报告中,我忘了具体说明了,这里做一下补充。
就像YUV可以分为YUV420/YUV422/YUV444一样,其实都是以YUV来进行存储的,但是每个向量所占空间是不同的,NV格式也是一样的,这里还是推荐雷霄骅大神的博客要讲的更加详细通透,可惜天妒英才。
接下来我们依然要进行的是编译运行,运行后点击HDMI直播按钮,可以看到状态栏的输出也正常了!
我们同样打开VLC来查看一下直播的内容,可以看到直播一切正常,画面也很清晰。