qt软件开发:基于ffmpge设计的流媒体播放器(rtmp/rtsp)(代码片段)

DS小龙哥 DS小龙哥     2022-12-14     151

关键词:

一、环境介绍

操作系统: win10 64位

QT版本:  QT5.12.6

编译器:  MinGW 32

ffmpeg版本:  4.2.2

完整工程下载地址(下载即可编译运行): https://download.csdn.net/download/xiaolong1126626497/20644890

本工程使用的FFMPEG库下载地址:https://download.csdn.net/download/xiaolong1126626497/13328939

二、功能介绍

使用QT+ffmpeg设计的流媒体播放器,实时播放RTMP、RTSP视频流渲染显示。

测试大华摄像头、海康摄像头、CCTV直播频道等视频均可正常播放,实测延迟时间在1秒以内。

大华摄像头地址流媒体地址配置教程:https://blog.csdn.net/xiaolong1126626497

部分工程代码截图:

 软件运行效果:

 CCVT的RTMP流拉取效果:

  CCVT的RTMP流拉取效果--隐藏日志窗口:

 

大华摄像头的RTMP流拉取效果:

大华摄像头的RTSP流拉取效果:

 

三、RTMP与RTSP协议介绍

RTMP

RTMP是Real Time Messaging Protocol(实时消息传输协议)的首字母缩写。该协议基于TCP,是一个协议族,包括RTMP基本协议及RTMPT/RTMPS/RTMPE等多种变种。RTMP是一种设计用来进行实时数据通信的网络协议,主要用来在Flash/AIR平台和支持RTMP协议的流媒体/交互服务器之间进行音视频和数据通信。支持该协议的软件包括Adobe Media Server/Ultrant Media Server/red5等。RTMP与HTTP一样,都属于TCP/IP四层模型的应用层。

RTMP又是Routing Table Maintenance Protocol(路由选择表维护协议)的缩写。 在 AppleTalk 协议组中,路由选择表维护协议(RTMP,Routing Table Maintenance Protocol)是一种传输层协议,它在 AppleTalk 路由器中建立并维护路由选择表。RTMP 基于路由选择信息协议(RIP)。正如 RIP 一样,RTMP 使用跳数作为路由计量标准。一个数据包从源 网络发送到目标网络,必须通过的路由器或其它中间介质节点数目的计算结果即为跳数。

RTSP

RTSP(Real Time Streaming Protocol),RFC2326,实时流传输协议,是TCP/IP协议体系中的一个应用层协议,由哥伦比亚大学、网景和RealNetworks公司提交的IETF RFC标准。该协议定义了一对多应用程序如何有效地通过IP网络传送多媒体数据。RTSP在体系结构上位于RTP和RTCP之上,它使用TCP或UDP完成数据传输。HTTP与RTSP相比,HTTP请求由客户机发出,服务器作出响应;使用RTSP时,客户机和服务器都可以发出请求,即RTSP可以是双向的。RTSP是用来控制声音或影像的多媒体串流协议,并允许同时多个串流需求控制,传输时所用的网络通讯协定并不在其定义的范围内,服务器端可以自行选择使用TCP或UDP来传送串流内容,它的语法和运作跟HTTP 1.1类似,但并不特别强调时间同步,所以比较能容忍网络延迟。而前面提到的允许同时多个串流需求控制(Multicast),除了可以降低服务器端的网络用量,更进而支持多方视讯会议(Video Conference)。因为与HTTP1.1的运作方式相似,所以代理服务器〈Proxy〉的快取功能〈Cache〉也同样适用于RTSP,并因RTSP具有重新导向功能,可视实际负载情况来转换提供服务的服务器,以避免过大的负载集中于同一服务器而造成延迟。
 

四、FFMPEG介绍

FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制、转换以及流化音视频的完整解决方案。它包含了非常先进的音频/视频编解码库libavcodec,为了保证高可移植性和编解码质量,libavcodec里很多code都是从头开发的。

多媒体视频处理工具FFmpeg有非常强大的功能包括视频采集功能、视频格式转换、视频抓图、给视频加水印等。

FFmpeg在Linux平台下开发,但它同样也可以在其它操作系统环境中编译运行,包括Windows、Mac OS X等。这个项目最早由Fabrice Bellard发起,2004年至2015年间由Michael Niedermayer主要负责维护。许多FFmpeg的开发人员都来自MPlayer项目,而且当前FFmpeg也是放在MPlayer项目组的服务器上。项目的名称来自MPEG视频编码标准,前面的"FF"代表"Fast Forward"。FFmpeg编码库可以使用GPU加速。

五、核心代码

 

5.1 xxx.pro :MinGW配置方式

QT       += core gui
QT       += multimediawidgets
QT       += xml
QT       += multimedia
QT       += network
QT       += widgets
QT       += serialport
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \\
    Thread_FFMPEG_LaLiu.cpp \\
    main.cpp \\
    videoplayer_showvideowidget.cpp \\
    widget.cpp

HEADERS += \\
    Thread_FFMPEG_LaLiu.h \\
    videoplayer_showvideowidget.h \\
    widget.h

FORMS += \\
    widget.ui

# Default rules for deployment.
qnx: target.path = /tmp/$$TARGET/bin
else: unix:!android: target.path = /opt/$$TARGET/bin
!isEmpty(target.path): INSTALLS += target

win32

    message('运行win32版本')
    INCLUDEPATH+=C:/FFMPEG/ffmpeg_x86_4.2.2/include
    LIBS+=C:/FFMPEG/ffmpeg_x86_4.2.2/bin/av*
    LIBS+=C:/FFMPEG/ffmpeg_x86_4.2.2/bin/sw*
    LIBS+=C:/FFMPEG/ffmpeg_x86_4.2.2/bin/pos*


RESOURCES += \\
    image.qrc

RC_ICONS=main.ico

5.2 xxx.pro: VS编译器配置方式

QT       += core gui
QT       += multimediawidgets
QT       += xml
QT       += multimedia
QT       += network
QT       += widgets
QT       += serialport
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \\
    Thread_FFMPEG_LaLiu.cpp \\
    main.cpp \\
    videoplayer_showvideowidget.cpp \\
    widget.cpp

HEADERS += \\
    Thread_FFMPEG_LaLiu.h \\
    videoplayer_showvideowidget.h \\
    widget.h

FORMS += \\
    widget.ui

# Default rules for deployment.
qnx: target.path = /tmp/$$TARGET/bin
else: unix:!android: target.path = /opt/$$TARGET/bin
!isEmpty(target.path): INSTALLS += target

win32

    message('运行win32版本')
    INCLUDEPATH+=C:/FFMPEG/ffmpeg_x86_x64_3.3.2/include
    LIBS+=C:/FFMPEG/ffmpeg_x86_x64_3.3.2/lib/avcodec.lib
    LIBS+=C:/FFMPEG/ffmpeg_x86_x64_3.3.2/lib/avformat.lib
    LIBS+=C:/FFMPEG/ffmpeg_x86_x64_3.3.2/lib/avfilter.lib
    LIBS+=C:/FFMPEG/ffmpeg_x86_x64_3.3.2/lib/avutil.lib
    LIBS+=C:/FFMPEG/ffmpeg_x86_x64_3.3.2/lib/swresample.lib
    LIBS+=C:/FFMPEG/ffmpeg_x86_x64_3.3.2/lib/swscale.lib



RESOURCES += \\
    image.qrc

RC_ICONS=main.ico

5.3 widget.h

#ifndef WIDGET_H
#define WIDGET_H
#pragma execution_character_set("utf-8")
#include <QWidget>
#include <QCompleter>
#include "Thread_FFMPEG_LaLiu.h"
QT_BEGIN_NAMESPACE
namespace Ui  class Widget; 
QT_END_NAMESPACE

//主线程
class Widget : public QWidget

    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
    void SetStyle(const QString &qssFile);
    void Log_Text_Display(QPlainTextEdit *plainTextEdit_log,QString text);
private slots:
    void Log_Display(QString text);
     void VideoDataDisplay(QImage image);
     void on_pushButton_start_clicked();
     void on_pushButton_stop_play_clicked();

     void on_pushButton_no_display_clicked();

private:
    Ui::Widget *ui;

    bool log_widge_state=true;
;

#endif // WIDGET_H

5.4 widget.cpp

#include "widget.h"
#include "ui_widget.h"

/*
 * 设置QT界面的样式
*/
void Widget::SetStyle(const QString &qssFile) 
    QFile file(qssFile);
    if (file.open(QFile::ReadOnly)) 
        QString qss = QLatin1String(file.readAll());
        qApp->setStyleSheet(qss);
        QString PaletteColor = qss.mid(20,7);
        qApp->setPalette(QPalette(QColor(PaletteColor)));
        file.close();
    
    else
    
        qApp->setStyleSheet("");
    



Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)

    ui->setupUi(this);

    /*基本设置*/
   // this->SetStyle(":/images/blue.css");     //设置样式表
    this->setWindowIcon(QIcon(":/main.ico")); //设置图标
    this->setWindowTitle("流媒体播放器");

    //构建默认地址
    QStringList listyear;
    listyear<<"rtmp://10.0.0.13:8888/live/video"
           <<"rtmp://58.200.131.2:1935/livetv/cctv14"
           <<"rtsp://admin:vioovi2021@10.0.0.2:554/cam/realmonitor?channel=1&subtype=0"
           ; //列表
    QCompleter *year = new QCompleter(listyear);//构建自动补全器
    ui->lineEdit_rtmp_url->setCompleter(year); //设置自动补全器功能

    //连接拉流线程的图像输出信号
    connect(&thread_laliu,SIGNAL(VideoDataOutput(QImage )),this,SLOT(VideoDataDisplay(QImage )));
    //连接拉流线程的日志信息
    connect(&thread_laliu,SIGNAL(LogSend(QString)),this,SLOT(Log_Display(QString)));


Widget::~Widget()

    delete ui;


//视频刷新显示
void Widget::VideoDataDisplay(QImage image)

    ui->widget_display->slotGetOneFrame(image);


/*日志显示*/
void Widget::Log_Text_Display(QPlainTextEdit *plainTextEdit_log,QString text)

    plainTextEdit_log->insertPlainText(text);
    //移动滚动条到底部
    QScrollBar *scrollbar = plainTextEdit_log->verticalScrollBar();
    if(scrollbar)
    
        scrollbar->setSliderPosition(scrollbar->maximum());
    


//日志显示
void Widget::Log_Display(QString text)

    Log_Text_Display(ui->plainTextEdit_log,text);


//开始拉流
void Widget::on_pushButton_start_clicked()

    on_pushButton_stop_play_clicked();
    //设置地址
    thread_laliu.SetRTMPAddr(ui->lineEdit_rtmp_url->text());
    //开始运行线程
    thread_laliu.start();



/*
工程: ffmpeg_Laliu
日期: 2021-07-30
作者: DS小龙哥
环境: win10 QT5.12.6 MinGW32
功能: 停止播放
*/
void Widget::on_pushButton_stop_play_clicked()

    if(thread_laliu.isRunning())
    
        thread_laliu.Exit_process();
        thread_laliu.quit();
        thread_laliu.wait();
    


/*
工程: ffmpeg_Laliu
日期: 2021-07-30
作者: DS小龙哥
环境: win10 QT5.12.6 MinGW32
功能: 隐藏日志窗口
*/
void Widget::on_pushButton_no_display_clicked()

    log_widge_state=!log_widge_state;
    ui->groupBox->setVisible(log_widge_state);


5.5  widget渲染窗口--渲染视频画面


#include "videoplayer_showvideowidget.h"

#include <QPainter>

VideoPlayer_ShowVideoWidget::VideoPlayer_ShowVideoWidget(QWidget *parent) :
    QWidget(parent)

    m_nRotateDegree=0;
    this->setMouseTracking(true);


VideoPlayer_ShowVideoWidget::~VideoPlayer_ShowVideoWidget()




void VideoPlayer_ShowVideoWidget::Set_Rotate(int Rotate)

    m_nRotateDegree=Rotate;


void VideoPlayer_ShowVideoWidget::paintEvent(QPaintEvent *event)

    QPainter painter(this);

    painter.setRenderHint(QPainter::Antialiasing);
    painter.setRenderHint(QPainter::TextAntialiasing);
    painter.setRenderHint(QPainter::SmoothPixmapTransform);
    painter.setRenderHint(QPainter::HighQualityAntialiasing);

    painter.setBrush(Qt::black);
    painter.drawRect(0,0,this->width(),this->height()); //先画成黑色

    if (mImage.size().width() <= 0) return;

    //将图像按比例缩放成和窗口一样大小
    QImage img = mImage.scaled(this->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation); //这里效率比较低下  还不知道如何优化

    //画面旋转
    if(m_nRotateDegree > 0)
    
        QTransform matrix;
        matrix.rotate(m_nRotateDegree);
        img = img.transformed(matrix, Qt::SmoothTransformation);
    

    int x = this->width() - img.width();
    int y = this->height() - img.height();

    x /= 2;
    y /= 2;

    painter.drawImage(QPoint(x,y),img); //画出图像




void VideoPlayer_ShowVideoWidget::slotGetOneFrame(QImage img)

    src_mImage =mImage = img;
    update(); //调用update将执行 paintEvent函数


/*
工程: QtAV_VideoPlayer
日期: 2021-03-24
作者: DS小龙哥
环境: win10 QT5.12.6 MinGW32
功能: 获取原图数据
*/
QImage VideoPlayer_ShowVideoWidget::GetImage()

    return src_mImage.copy();


/*
工程: QtAV_VideoPlayer
日期: 2021-03-25
作者: DS小龙哥
环境: win10 QT5.12.6 MinGW32
功能: 鼠标双击事件
*/
void VideoPlayer_ShowVideoWidget::mouseDoubleClickEvent(QMouseEvent *e)

    emit s_VideoWidgetEvent(1);


qt软件开发-基于ffmpeg设计视频播放器-支持流媒体地址播放

QT软件开发-基于FFMPEG设计视频播放器-支持软解与硬解(一)https://xiaolong.blog.csdn.net/article/details/126832537QT软件开发-基于FFMPEG设计视频播放器-支持软解与硬解(二)https://xiaolong.blog.csdn.net/article/details/126833434QT软件开发-基于FFMPEG设... 查看详情

基于libmpv内核设计开发的视频播放器(代码片段)

...两种形式:窗口嵌入、OpenGL(3)演示属性设置方式:rtsp/rtmp流媒体播放、开启GPU硬件解码等等。(4)解决例程运行时会出现的错误。一、前言mpv 查看详情

qt软件开发:基于qtav设计的视频播放器(代码片段)

一、环境介绍操作系统: win1064位QT版本:  QT5.12.6编译器:  MinGW32QtAV版本:  QtAV-1.12.0FFMPEG版本:  ffmpeg3.1 使用的是QtAV提供的包,直接使用完整源码下载:  https://download.csdn.net/download/xiaolong1126626497/19759245二、编译QTAV模块参考... 查看详情

qt软件开发-基于ffmpeg设计视频播放器-支持软解与硬解-完整例子

QT软件开发-基于FFMPEG设计视频播放器-支持软解与硬解(一)https://xiaolong.blog.csdn.net/article/details/126832537QT软件开发-基于FFMPEG设计视频播放器-支持软解与硬解(二)https://xiaolong.blog.csdn.net/article/details/126833434QT软件开发-基于FFMPEG设... 查看详情

qt软件开发:基于libvlc内核设计视频播放器(代码片段)

一、环境介绍操作系统: win1064位QT版本:  QT5.12.6编译器:  MinGW32libvlc版本:  3.0.12完整工程下载地址(下载即可编译运行): https://download.csdn.net/download/xiaolong1126626497/20479530二、播放器运行效果与功能介绍 播放器的功能介绍:1.图像... 查看详情

qt软件开发:基于libvlc内核设计视频播放器(代码片段)

一、环境介绍操作系统: win1064位QT版本:  QT5.12.6编译器:  MinGW32libvlc版本:  3.0.12完整工程下载地址(下载即可编译运行): https://download.csdn.net/download/xiaolong1126626497/20479530二、播放器运行效果与功能介绍 播放器的功能介绍:1.图像... 查看详情

qt软件开发-基于ffmpeg设计视频播放器-支持软解与硬解(代码片段)

一、前言在前一章里介绍了ffmpeg基本概念,完成了ffmpeg对视频软件解码并渲染,实现了基本播放器功能设计。这篇文章介绍ffmpeg硬件加速解码视频的流程,完成基本播放器设计。我这里开发视频播放器用到的环境介绍:ffmpeg版本... 查看详情

qt软件开发-基于ffmpeg设计视频播放器-支持软解与硬解(代码片段)

一、前言在前一章里介绍了ffmpeg基本概念,完成了ffmpeg对视频解码并渲染,实现了基本播放器功能设计。只是之前都只是解码了图像,忽略了音频数据,这篇文章介绍ffmpeg如何解码音频,制作一个音乐播放器,为后续的完整播放... 查看详情

qt软件开发-基于ffmpeg设计视频播放器-支持软解与硬解(代码片段)

一、前言前面几篇文章里分别介绍了ffmpeg软解、硬解、音频解码,完成视频帧渲染,音频解码播放。之前做的视频播放器里,虽然也使用了硬件加速解码,解码确实快,但是渲染都采用QWidget方式渲染绘制,占用CPU较高,并且采... 查看详情

基于libmpv内核设计开发的视频播放器-完整版(代码片段)

...主要是功能开发。里有libmpv的API接口完成一个完整可用的播放器开发,设计好UI界面,增加自己想要的功能。详细功能如下:( 查看详情

基于树莓派4b设计的音视频播放器(从0开始)

...音乐、网络音乐,当做FM网络收音机。软件采用Qt设计、播放器引擎采用ffmpeg。当前的硬件选择的是树莓派4B,烧写官方系统,完成最终的开发。本篇文章主要从树莓派开箱体验、系统烧写、远程登录、Qt开发环境搭建、FFMPEG相关... 查看详情

基于libmpv内核设计开发的视频播放器-简易demo(代码片段)

完整版请看这里:https://xiaolong.blog.csdn.net/article/details/127027445环境介绍:操作系统:win1064位Qt版本:Qt5.12.6libmpv:采用最新版--截止文章编写。mpv-dev-x86_64-v3-20220918-git内容:(1)演示libmpv源、库下载流程(2)演示libmpv二次开发渲染的两种形... 查看详情

基于libmpv内核设计开发的视频播放器-简易demo(代码片段)

完整版请看这里:https://xiaolong.blog.csdn.net/article/details/127027445环境介绍:操作系统:win1064位Qt版本:Qt5.12.6libmpv:采用最新版--截止文章编写。mpv-dev-x86_64-v3-20220918-git内容:(1)演示libmpv源、库下载流程(2)演示libmpv二次开发渲染的两种形... 查看详情

基于libmpv内核设计开发的视频播放器-高级版(代码片段)

...已经对libmpv做了详细的介绍,第二篇文章里完成了完整的播放器开发,设计了UI,实现了播放器的基本功能。这一篇里对libmpv完成功能扩展,增加进度条预览图的支持(鼠标放在进度条上弹出预览窗口),支持视频章节解析渲染... 查看详情

基于libmpv内核设计开发的视频播放器-高级版(代码片段)

...已经对libmpv做了详细的介绍,第二篇文章里完成了完整的播放器开发,设计了UI,实现了播放器的基本功能。这一篇里对libmpv完成功能扩展,增加进度条预览图的支持(鼠标放在进度条上弹出预览窗口),支持视频章节解析渲染... 查看详情

音频频谱显示-基于fmod设计音乐播放器并动态显示频谱图(代码片段)

...26626497/article/details/126971535音频频谱显示-基于fmod设计音乐播放器并动态显示频谱图(二)https://blog.csdn.net/xiaolong1126626497/article/details/126973994一、前言在做音乐播放器、音频编辑软件,录音软件、音频相关其他软件时,经常有显示... 查看详情

avplayer视频播放

...支持播放从本地,分步下载或通过HTTPLiveStreaming协议得到的流媒体,并在多种播放场景中播放这些视频资源.开发者通过AVPlayer框架提供的应用程序接口来开发控制播放基于时间的媒体的用户界面.AVPlayer只管理一 查看详情

qt程序集成easyplayer-rtsp流媒体播放器出现画面闪烁是什么原因?

TSINGSEE青犀视频旗下的视频平台都具备灵活的视频能力、可拓展性强、开放度高,同时为了满足用户的集成与二次开发需求,我们也提供了丰富的API接口及SDK,便于用户调用和集成。TSINGSEE青犀视频的各个视频平台可... 查看详情