GB28181学习(六)——实时视音频点播(数据传输部分)

2023-10-06 13:56

本文主要是介绍GB28181学习(六)——实时视音频点播(数据传输部分),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

GB28181系列文章:

总述:https://blog.csdn.net/www_dong/article/details/132515446

注册与注销:https://blog.csdn.net/www_dong/article/details/132654525

心跳保活:https://blog.csdn.net/www_dong/article/details/132796612

网络设备信息查询:https://blog.csdn.net/www_dong/article/details/132912085

视音频点播(信令传输部分):https://blog.csdn.net/www_dong/article/details/132950064

媒体服务器

提供媒体流的转发、媒体存储、历史媒体信息的检索和点播服务的服务器。

设计方案

  • jrtplib+jthread:监听、视频数据接收与转发;
  • libmpeg:对ps流解复用;
  • ffmpeg:数据解码;
  • Qt(QOpenGLWidget):视频播放;

数据接收

jrtplib

jrtplib是一个面向对象的RTP封装库。

特点:

  • 该库使用户能够发送和接收数据使用RTP,无需担心SSRC冲突、调度和传输RTCP数据等。用户只需提供库通过发送有效负载数据,库为用户提供访问权限输入RTP和RTCP数据;
  • 该库提供了几个类,这些类有助于创建RTP应用程序。大多数用户可能只需要RTPSession类来构建应用程序,或者从RTPSecureSession派生一个类来支持SRTP。这些类提供了发送RTP数据的必要功能,并在内部处理RTCP部分;

jthread

jrtplib的使用依赖于jthread,使用方式用两种:

  1. 用 jthread 库提供的线程自动在后台执行对数据的接收;
  2. 用户自己调用 RTPSession 中的 Poll 方法;

下载

下载地址:https://research.edm.uhasselt.be/jori/page/Cs/JrtplibOld.html 。

该项目目前使用的是jrtplib-3.11.2.zip+jthread-1.3.3.zip。下载完成后使用cmake生成windows下.sln工程编译生成静态库使用。

流程

  • 数据接收流程,该流程目前在线程中处理。
uint8_t payload;
while (m_running)
{Poll();BeginDataAccess();if (GotoFirstSourceWithData()){do{RTPPacket* packet = nullptr;while (nullptr != (packet = GetNextPacket())){payload = packet->GetPayloadType();if (0 == payload){DeletePacket(packet);continue;}// ...// rtp载荷数据处理流程DeletePacket(packet);}} while (GotoNextSourceWithData());}EndDataAccess();Sleep(30);
}Destroy();

数据解复用

该流程使用的是libmpeg库,下载地址:https://github.com/ireader/media-server.git

由于国标流是ps封装,故需要将ps流解复用获取原始数据。

解复用代码流程:

static void* Alloc(void* /*param*/, size_t bytes)
{return malloc(bytes);
}static void Free(void* /*param*/, void* packet)
{free(packet);
}static int Write(void* param, int avtype, void* pes, size_t bytes)
{assert(param);CPSParse* parse = (CPSParse*)param;return parse->Package(avtype, pes, bytes);
}CPSParse::CPSParse()
{struct ps_muxer_func_t func;func.alloc = Alloc;func.free = Free;func.write = Write;m_ps = ps_muxer_create(&func, this);m_ps_stream = ps_muxer_add_stream(m_ps, STREAM_VIDEO_H264, nullptr, 0);
}CPSParse::~CPSParse()
{if (m_ps)ps_muxer_destroy(m_ps);
}int CPSParse::InputData(void* data, int len)
{if (nullptr == m_ps || nullptr == data || len <= 0)return -1;uint64_t clock = time64_now();if (0 == m_ps_clock)m_ps_clock = clock;ps_muxer_input(m_ps, m_ps_stream, 0, (clock - m_ps_clock) * 90, (clock - m_ps_clock) * 90, data, len);return 0;
}int CPSParse::Package(int avtype, void* payload, size_t bytes)
{// 数据处理return 0;
}

数据解码

通过对ps数据流解复用获取原始数据,本项目通过ffmpeg对原始数据进行解码获取yuv数据。

关于ffmpeg的使用,可以查看:

音视频播放器设计(一)——环境配置:https://blog.csdn.net/www_dong/article/details/124459467

音视频播放器设计(二)——ffmpeg视频处理流程:https://blog.csdn.net/www_dong/article/details/124561444

音视频播放器设计(三)——OpenGL绘制视频:https://blog.csdn.net/www_dong/article/details/124638515

音视频播放器设计(四)——ffmpeg音频处理流程:https://blog.csdn.net/www_dong/article/details/125323635

视频播放

通过ffmpeg解码获取yuv数据,本项目通过qt的QOpenGLWidget对yuv数据进行渲染达到播放的目的。

  • 使用方法:
    • 新建一个PlayWidget类继承于QOpenGLWidget;
    • 将ffmpeg解码后的yuv数据传入PlayWidget类,保存并调用update函数;
    • update()被调用后,QOpenGLWidget::paintGL()会自动被调用,在里面进行显示;
    • 使用QOpenGLFunctions::glTexImage2D传入一帧数据进行显示;
#include <QOpenGLShaderProgram>
#include <QOpenGLFunctions>
#include <QOpenGLTexture>class PlayWidget : public QOpenGLWidget, protected QOpenGLFunctions
{public:PlayWidget(QWidget *parent = nullptr);virtual ~PlayWidget();// ...
};

效果展示

在这里插入图片描述

这篇关于GB28181学习(六)——实时视音频点播(数据传输部分)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/153223

相关文章

OpenCV实现实时颜色检测的示例

《OpenCV实现实时颜色检测的示例》本文主要介绍了OpenCV实现实时颜色检测的示例,通过HSV色彩空间转换和色调范围判断实现红黄绿蓝颜色检测,包含视频捕捉、区域标记、颜色分析等功能,具有一定的参考... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间

Go学习记录之runtime包深入解析

《Go学习记录之runtime包深入解析》Go语言runtime包管理运行时环境,涵盖goroutine调度、内存分配、垃圾回收、类型信息等核心功能,:本文主要介绍Go学习记录之runtime包的... 目录前言:一、runtime包内容学习1、作用:① Goroutine和并发控制:② 垃圾回收:③ 栈和

Android学习总结之Java和kotlin区别超详细分析

《Android学习总结之Java和kotlin区别超详细分析》Java和Kotlin都是用于Android开发的编程语言,它们各自具有独特的特点和优势,:本文主要介绍Android学习总结之Ja... 目录一、空安全机制真题 1:Kotlin 如何解决 Java 的 NullPointerExceptio

重新对Java的类加载器的学习方式

《重新对Java的类加载器的学习方式》:本文主要介绍重新对Java的类加载器的学习方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、介绍1.1、简介1.2、符号引用和直接引用1、符号引用2、直接引用3、符号转直接的过程2、加载流程3、类加载的分类3.1、显示

使用Python实现实时金价监控并自动提醒功能

《使用Python实现实时金价监控并自动提醒功能》在日常投资中,很多朋友喜欢在一些平台买点黄金,低买高卖赚点小差价,但黄金价格实时波动频繁,总是盯着手机太累了,于是我用Python写了一个实时金价监控... 目录工具能干啥?手把手教你用1、先装好这些"食材"2、代码实现讲解1. 用户输入参数2. 设置无头浏

Java学习手册之Filter和Listener使用方法

《Java学习手册之Filter和Listener使用方法》:本文主要介绍Java学习手册之Filter和Listener使用方法的相关资料,Filter是一种拦截器,可以在请求到达Servl... 目录一、Filter(过滤器)1. Filter 的工作原理2. Filter 的配置与使用二、Listen

一文详解如何在Python中从字符串中提取部分内容

《一文详解如何在Python中从字符串中提取部分内容》:本文主要介绍如何在Python中从字符串中提取部分内容的相关资料,包括使用正则表达式、Pyparsing库、AST(抽象语法树)、字符串操作... 目录前言解决方案方法一:使用正则表达式方法二:使用 Pyparsing方法三:使用 AST方法四:使用字

Mysql删除几亿条数据表中的部分数据的方法实现

《Mysql删除几亿条数据表中的部分数据的方法实现》在MySQL中删除一个大表中的数据时,需要特别注意操作的性能和对系统的影响,本文主要介绍了Mysql删除几亿条数据表中的部分数据的方法实现,具有一定... 目录1、需求2、方案1. 使用 DELETE 语句分批删除2. 使用 INPLACE ALTER T

Java进阶学习之如何开启远程调式

《Java进阶学习之如何开启远程调式》Java开发中的远程调试是一项至关重要的技能,特别是在处理生产环境的问题或者协作开发时,:本文主要介绍Java进阶学习之如何开启远程调式的相关资料,需要的朋友... 目录概述Java远程调试的开启与底层原理开启Java远程调试底层原理JVM参数总结&nbsMbKKXJx

Java深度学习库DJL实现Python的NumPy方式

《Java深度学习库DJL实现Python的NumPy方式》本文介绍了DJL库的背景和基本功能,包括NDArray的创建、数学运算、数据获取和设置等,同时,还展示了如何使用NDArray进行数据预处理... 目录1 NDArray 的背景介绍1.1 架构2 JavaDJL使用2.1 安装DJL2.2 基本操