当前位置: 首页 > news >正文

ffmpeg RTP PS推流

要实现 CRtpSendPs 类,使其能够将 H264 数据通过 RTP PS 流推送到指定的 URL,并支持 TCP 和 UDP 传输方式,您需要使用 FFmpeg 库。以下是该类的实现示例,包括必要的初始化、推流和退出函数。

步骤

  1. 初始化 FFmpeg 库:需要初始化 FFmpeg 网络、格式和编码器相关的库。
  2. 配置 RTP 传输:使用 RTP 封装 PS (Program Stream) 格式。
  3. 推送数据:接收 H264 数据并将其封装为 RTP 包,发送到指定的目标 URL(支持 UDP 和 TCP)。
  4. 退出处理:释放相关资源。

完整代码实现

 
#include <iostream>
#include <string>
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libavutil/avutil.h>
#include <libavdevice/avdevice.h>
#include <libavfilter/avfilter.h>
#include <libswscale/swscale.h>class CRtpSendPs
{
public:CRtpSendPs();~CRtpSendPs();int Init(const char *url, bool bUdpOrTcp);  // 初始化,设置目标 URL 和传输协议int PushStream(const void *pH264Data, uint32_t u32Len);  // 推送视频数据int Exit();  // 清理资源private:AVFormatContext *outputFmtCtx;AVStream *outputStream;AVCodecContext *codecCtx;AVPacket pkt;bool isUdp;std::string outputUrl;bool isInitialized;
};CRtpSendPs::CRtpSendPs() : outputFmtCtx(nullptr), outputStream(nullptr), codecCtx(nullptr), isInitialized(false)
{av_register_all();avformat_network_init();avcodec_register_all();avdevice_register_all();isUdp = true;isInitialized = false;
}CRtpSendPs::~CRtpSendPs()
{Exit();
}int CRtpSendPs::Init(const char *url, bool bUdpOrTcp)
{if (isInitialized) {std::cerr << "Already initialized!" << std::endl;return -1;}isUdp = bUdpOrTcp;outputUrl = url;// Create output contextAVOutputFormat *fmt = av_guess_format(NULL, outputUrl.c_str(), NULL);if (!fmt) {std::cerr << "Could not guess output format!" << std::endl;return -1;}int ret = avformat_alloc_output_context2(&outputFmtCtx, fmt, NULL, outputUrl.c_str());if (ret < 0) {std::cerr << "Failed to create output context!" << std::endl;return ret;}// Create a new stream for the outputoutputStream = avformat_new_stream(outputFmtCtx, NULL);if (!outputStream) {std::cerr << "Failed to create new stream!" << std::endl;return AVERROR(ENOMEM);}// Setup codec parameters (for H264)AVCodec *encoder = avcodec_find_encoder(AV_CODEC_ID_H264);if (!encoder) {std::cerr << "H264 encoder not found!" << std::endl;return AVERROR_ENCODER_NOT_FOUND;}codecCtx = avcodec_alloc_context3(encoder);if (!codecCtx) {std::cerr << "Failed to allocate codec context!" << std::endl;return AVERROR(ENOMEM);}codecCtx->codec_id = AV_CODEC_ID_H264;codecCtx->bit_rate = 1000000;codecCtx->width = 1920;codecCtx->height = 1080;codecCtx->time_base = {1, 30};  // 30 fpscodecCtx->gop_size = 12;codecCtx->max_b_frames = 3;codecCtx->pix_fmt = AV_PIX_FMT_YUV420P;ret = avcodec_open2(codecCtx, encoder, NULL);if (ret < 0) {std::cerr << "Failed to open codec!" << std::endl;return ret;}// Copy codec parameters to the streamret = avcodec_parameters_from_context(outputStream->codecpar, codecCtx);if (ret < 0) {std::cerr << "Failed to copy codec parameters!" << std::endl;return ret;}// Open the output file or network streamif (!(outputFmtCtx->oformat->flags & AVFMT_NOFILE)) {ret = avio_open(&outputFmtCtx->pb, outputUrl.c_str(), AVIO_FLAG_WRITE);if (ret < 0) {std::cerr << "Failed to open output URL!" << std::endl;return ret;}}// Write the header of the file (or stream)ret = avformat_write_header(outputFmtCtx, NULL);if (ret < 0) {std::cerr << "Failed to write header!" << std::endl;return ret;}isInitialized = true;return 0;
}int CRtpSendPs::PushStream(const void *pH264Data, uint32_t u32Len)
{if (!isInitialized) {std::cerr << "Not initialized!" << std::endl;return -1;}// Create a packet and fill it with H264 dataav_init_packet(&pkt);pkt.data = (uint8_t *)pH264Data;pkt.size = u32Len;pkt.stream_index = outputStream->index;pkt.flags |= AV_PKT_FLAG_KEY;  // Assuming it's a keyframe, adjust if needed// Write the packet to the RTP streamint ret = av_write_frame(outputFmtCtx, &pkt);if (ret < 0) {std::cerr << "Error writing frame!" << std::endl;return ret;}return 0;
}int CRtpSendPs::Exit()
{if (!isInitialized) {return 0;  // Already exited}av_write_trailer(outputFmtCtx);// Close the output stream and free resourcesif (outputFmtCtx && !(outputFmtCtx->oformat->flags & AVFMT_NOFILE)) {avio_closep(&outputFmtCtx->pb);}avcodec_free_context(&codecCtx);avformat_free_context(outputFmtCtx);isInitialized = false;return 0;
}

代码说明

  1. CRtpSendPs 类的构造函数和析构函数

    • Init():初始化 FFmpeg 输出格式和编码器配置,设置输出 URL 并建立连接。
    • PushStream():接受一帧 H264 数据并将其封装为 RTP 包,然后通过网络发送。
    • Exit():释放资源并关闭输出流。
  2. FFmpeg 配置

    • 使用 avformat_alloc_output_context2() 创建输出流上下文。
    • 使用 avcodec_find_encoder() 查找 H264 编码器,初始化编码器上下文。
    • 使用 av_write_frame() 将数据包发送到指定的输出 URL(支持 RTP 协议)。
  3. RTP 传输:通过 RTP 推送数据流,支持 UDP 和 TCP(通过 URL 中的协议部分决定)。

编译命令

在编译前,确保已经安装了 FFmpeg 库。如果没有安装,您可以使用以下命令:

sudo apt-get install libavformat-dev libavcodec-dev libavutil-dev libavdevice-dev libswscale-dev

然后使用以下命令来编译代码:

 
g++ -o rtp_send_ps rtp_send_ps.cpp -lavformat -lavcodec -lavutil -lavdevice -lswscale -lavfilter -lm -lz

运行示例

 
./rtp_send_ps rtp://192.168.0.49:5000

此命令将会把 H264 数据通过 RTP 协议推送到目标 IP 地址 192.168.0.49,端口 5000

注意事项

  • 您需要确保目标服务器或设备能够接收 RTP 流。
  • 在真实应用中,PushStream() 中的 H264 数据可以从文件或网络中获取,并通过该函数传输。

相关文章:

ffmpeg RTP PS推流

要实现 CRtpSendPs 类&#xff0c;使其能够将 H264 数据通过 RTP PS 流推送到指定的 URL&#xff0c;并支持 TCP 和 UDP 传输方式&#xff0c;您需要使用 FFmpeg 库。以下是该类的实现示例&#xff0c;包括必要的初始化、推流和退出函数。 步骤 初始化 FFmpeg 库&#xff1a;…...

Rust语言俄罗斯方块(漂亮的界面案例+详细的代码解说+完美运行)

tetris-demo A Tetris example written in Rust using Piston in under 500 lines of code 项目地址: https://gitcode.com/gh_mirrors/te/tetris-demo 项目介绍 "Tetris Example in Rust, v2" 是一个用Rust语言编写的俄罗斯方块游戏示例。这个项目不仅是一个简单…...

NUMA架构及在极速网络IO场景下的优化实践

NUMA技术原理 NUMA架构概述 随着多核CPU的普及&#xff0c;传统的对称多处理器&#xff08;SMP&#xff09;架构逐渐暴露出性能瓶颈。为了应对这一问题&#xff0c;非一致性内存访问&#xff08;NUMA, Non-Uniform Memory Access&#xff09;架构应运而生。NUMA架构是一种内存…...

Brain.js 用于浏览器的 GPU 加速神经网络

Brain.js 是一个强大的 JavaScript 库&#xff0c;它允许开发者在浏览器和 Node.js 环境中构建和训练神经网络 。这个库的目的是简化机器学习模型的集成过程&#xff0c;使得即使是没有深厚机器学习背景的开发者也能快速上手 。 概述 Brain.js 提供了易于使用的 API&#xff…...

Linux——用户级缓存区及模拟实现fopen、fweite、fclose

linux基础io重定向-CSDN博客 文章目录 目录 文章目录 什么是缓冲区 为什么要有缓冲区 二、编写自己的fopen、fwrite、fclose 1.引入函数 2、引入FILE 3.模拟封装 1、fopen 2、fwrite 3、fclose 4、fflush 总结 前言 用快递站讲述缓冲区 收件区&#xff08;类比输…...

视觉感知与处理:解密计算机视觉的未来

文章目录 前言1. 计算机视觉的概述2. 计算机视觉的应用3. 运动感知与光流4. 人类视觉感知4.1 大脑中的视觉处理4.2 视觉缺陷与对比4.3 分辨率4.4 视觉错觉5. 图像采集与处理6. 图像处理流程7. 二值图像处理与分割8. 3D 机器视觉系统8.1 主动3D视觉8.2 立体视觉9. 商业机器视觉系…...

【大数据学习 | Spark-Core】广播变量和累加器

1. 共享变量 Spark两种共享变量&#xff1a;广播变量&#xff08;broadcast variable&#xff09;与累加器&#xff08;accumulator&#xff09;。 累加器用来对信息进行聚合&#xff0c;相当于mapreduce中的counter&#xff1b;而广播变量用来高效分发较大的对象&#xff0c…...

postgresql按照年月日统计历史数据

1.按照日 SELECT a.time,COALESCE(b.counts,0) as counts from ( SELECT to_char ( b, YYYY-MM-DD ) AS time FROM generate_series ( to_timestamp ( 2024-06-01, YYYY-MM-DD hh24:mi:ss ), to_timestamp ( 2024-06-30, YYYY-MM-DD hh24:mi:ss ), 1 days ) AS b GROUP BY tim…...

pywin32库 -- 读取word文档中的图形

文章目录 前置操作解析body中的图形解析页眉中的图形 前置操作 基于pywin32打开、关闭word应用程序&#xff1b; import pythoncom from win32com.client import Dispatch, GetActiveObjectdef get_word_instance():""" 获取word进程 实例"""py…...

GitLab使用示例

以下是从 新建分支开始&#xff0c;配置 GitLab CI/CD 的完整详细流程&#xff0c;涵盖每个步骤、配置文件路径和具体示例。 1. 新建分支并克隆项目 1.1 在 GitLab 上创建新分支 登录 GitLab&#xff0c;进入目标项目页面。依次点击 Repository > Branches。点击右上角 Ne…...

uniapp echarts tooltip formation 不识别html

需求&#xff1a; echarts 的tooltip 的域名太长&#xff0c;导致超出屏幕 想要让他换行 思路一&#xff1a; 用formation自定义样式实现换行 但是&#xff1a; uniapp 生成微信小程序&#xff0c; echart种的tooltip 的formation 识别不了html &#xff0c;自定义样式没办…...

3D扫描对文博行业有哪些影响?

三维扫描技术对文博行业产生了深远的影响&#xff0c;主要体现在以下几个方面&#xff1a; 一、高精度建模与数字化保护 三维扫描技术通过高精度扫描设备&#xff0c;能够捕捉到文物的每一个细节&#xff0c;包括形状、纹理、颜色等&#xff0c;从而生成逼真的3D模型。这些模…...

面试(十一)

目录 一.IO多路复用 二.为什么有IO多路复用机制? 三.IO多路复用的三种实现方式 3.1 select select 函数接口 select 使用示例 select 缺点 3.2 poll poll函数接口 poll使用示例 poll缺点 3.3 epoll epoll函数接口 epoll使用示例 epoll缺点 四. 进程和线程的区别…...

React-useState的使用

useState 是 React 提供的一个 Hook&#xff0c;允许你在函数组件中添加和管理状态&#xff08;state&#xff09;。在类组件中&#xff0c;状态管理通常是通过 this.state 和 this.setState 来实现的&#xff0c;而在函数组件中&#xff0c;useState 提供了类似的功能。 基本…...

设计模式之破环单例模式和阻止破坏

目录 1. 序列化和反序列化2. 反射 这里单例模式就不多说了 23种设计模式之单例模式 1. 序列化和反序列化 这里用饿汉式来做例子 LazySingleton import java.io.Serializable;public class LazySingleton implements Serializable {private static LazySingleton lazySinglet…...

11.19c++面向对象+单例模式

编写如下类: class File{ FILE* fp }; 1:构造函数&#xff0c;打开一个指定的文件 2:write函数 向文件中写入数据 3&#xff1a;read函数&#xff0c;从文件中读取数据&#xff0c;以string类型返回 代码实现&#xff1a; #include <iostream>using namespace std;class…...

一文了解TensorFlow是什么

TensorFlow是一个开源的机器学习框架&#xff0c;由Google开发并维护。它提供了一个灵活且高效的环境&#xff0c;用于构建和训练各种机器学习模型。 TensorFlow的基本概念包括&#xff1a; 张量&#xff08;Tensor&#xff09;&#xff1a;TensorFlow中的核心数据结构&#x…...

如何做好一份技术文档?

打造出色技术文档的艺术 在当今技术驱动的世界中&#xff0c;技术文档扮演着至关重要的角色。它不仅是工程师和开发人员之间交流的桥梁&#xff0c;更是产品和技术成功的隐形推手。一份优秀的技术文档宛如一张精准的航海图&#xff0c;能够引导读者穿越技术的迷雾&#xff0c;…...

Linux和Ubuntu的关系

Linux和Ubuntu的关系&#xff1a; 1. Linux本身是内核&#xff0c;Ubuntu系统是基于Linux内核的操作系统。 2. Linux内核操作系统的构成&#xff1a; 内核、shell、文件系统、应用程序 -应用程序&#xff1a;文本编辑器等 -文件系统&#xff1a;文件存放在存储设备上的组织方…...

软件工程之静态建模

静态模型&#xff1a;有助于设计包、类名、属性和方法特征标记&#xff08;但不是方法体&#xff09;的定义&#xff0c;例如UML类图。 用例的关系&#xff1a; 扩展关系&#xff1a; 扩展关系允许一个用例&#xff08;可选&#xff09;扩展另一个用例&#xff08;基用例&…...

PICO VR串流调试Unity程序

在平时写Unity的VR程序的时候&#xff0c;需要调试自己写的代码&#xff0c;但是有的时候会发现场景过于复杂&#xff0c;不是HMD一体机能运行的&#xff0c;或者为了能够更方便的调试&#xff0c;不需要每次都将程序部署到眼睛里&#xff0c;这样非常浪费时间&#xff0c;对于…...

自媒体图文视频自动生成软件|03| 页面和结构介绍

代码获取方式在文本末尾&#x1f51a; *代码获取方式在文本末尾&#x1f51a; *代码获取方式在文本末尾&#x1f51a; *代码获取方式在文本末尾&#x1f51a; 视频图片生成器 一个基于 Python 和 Web 的工具&#xff0c;用于生成带有文字和语音的视频以及图片。支持多种尺寸、…...

深入浅出摸透AIGC文生图产品SD(Stable Diffusion)

hihi,朋友们,时隔半年(24年11月),终于能腾出时间唠一唠SD了🤣,真怕再不唠一唠,就轮不到SD了,技术更新换代是在是太快! 朋友们,最近(24年2月)是真的没时间整理笔记,每天都在疯狂的学习Stable Diffusion和WebUI & ComfyUI,工作实在有点忙,实践期间在飞书上…...

解析生成对抗网络(GAN):原理与应用

目录 一、引言 二、生成对抗网络原理 &#xff08;一&#xff09;基本架构 &#xff08;二&#xff09;训练过程 三、生成对抗网络的应用 &#xff08;一&#xff09;图像生成 无条件图像生成&#xff1a; &#xff08;二&#xff09;数据增强 &#xff08;三&#xff…...

CodeIgniter URL结构

CodeIgniter 的URL 结构设计得简洁且易于管理。通常遵循以下模式&#xff1a; http://<domain>/<index_page>/<controller>/<method>/<parameters> 下面是每个部分的详细说明&#xff1a; <domain>&#xff1a; 这是你的网站域名&#…...

从 App Search 到 Elasticsearch — 挖掘搜索的未来

作者&#xff1a;来自 Elastic Nick Chow App Search 将在 9.0 版本中停用&#xff0c;但 Elasticsearch 拥有你构建强大的 AI 搜索体验所需的一切。以下是你需要了解的内容。 生成式人工智能的最新进展正在改变用户行为&#xff0c;激励开发人员创造更具活力、更直观、更引人入…...

鸿蒙本地模拟器 模拟TCP服务端的过程

鸿蒙模拟器模拟TCP服务端的过程涉及几个关键步骤&#xff0c;主要包括创建TCPSocketServer实例、绑定IP地址和端口、监听连接请求、接收和发送数据以及处理连接事件。以下是详细的模拟过程&#xff1a; **1.创建TCPSocketServer实例&#xff1a;**首先&#xff0c;需要导入鸿蒙…...

Qt/C++基于重力模拟的像素点水平堆叠效果

本文将深入解析一个基于 Qt/C 的像素点模拟程序。程序通过 重力作用&#xff0c;将随机分布的像素点下落并水平堆叠&#xff0c;同时支持窗口动态拉伸后重新计算像素点分布。 程序功能概述 随机生成像素点&#xff1a;程序在初始化时随机生成一定数量的像素点&#xff0c;每个…...

Zookeeper学习心得

本人学zookeeper时按照此文路线学的 Zookeeper学习大纲 - 似懂非懂视为不懂 - 博客园 一、Zookeeper安装 ZooKeeper 入门教程 - Java陈序员 - 博客园 Docker安装Zookeeper教程&#xff08;超详细&#xff09;_docker 安装zk-CSDN博客 二、 zookeeper的数据模型 ZooKeepe…...

嵌入式开发工程师面试题 - 2024/11/24

原文嵌入式开发工程师面试题 - 2024/11/24 转载请注明来源 1.若有以下定义语句double a[8]&#xff0c;*pa&#xff1b;int i5&#xff1b;对数组元素错误的引用是&#xff1f; A *a B a[5] C *&#xff08;p1&#xff09; D p[8] 解析&#xff1a; 在 C 或 C 语言中&am…...

如何做招聘网站统计表/百度搜索指数和资讯指数

查看Linux ARP缓存老化时间cat /proc/sys/net/ipv4/neigh/eth0/base_reachable_time同目录下还有一个文件gc_stale_time&#xff0c;官方解释如下&#xff1a;Determines how often to check for stale neighbour entries.When a neighbour entry is considered stale it is re…...

wordpress设置安全/成都网站seo外包

2019独角兽企业重金招聘Python工程师标准>>> 对工具类的功能来说&#xff0c;与其在微信中找各种接口不如直接调用其他wap站更好&#xff0c;&#xff08;http://r2.mo.baidu.com/webapp_html.php?version4_0&fnwebpage_flash&#xff09;有一些wap站可以参考&…...

做视频网站收入/推广引流吸引人的标题

g的编译选项介绍&#xff1a; -WI的理解&#xff0c;gcc的-WI,xxx选项似乎是在 gcc 中使用 ld 链接选项时候的编译器选项 -L: “链接” 的时候&#xff0c;去找的链接库的目录 - rpath&#xff08;或 - R &#xff0c;这似乎是一个内容&#xff09;&#xff0c;意思是“运行…...

中国万网轻云服务器 如何发布网站/如何建立自己的网站平台

mysql数据库中">以百度地图的Place API为例&#xff0c;在vs2010中获取某一类型(如酒店)的POI数据(以xml文件方式存储)&#xff0c;并导入mysql数据库中。第一步&#xff1a;打开vs2010&#xff0c;并建立一个windows窗体应用程序&#xff0c;在窗体中添加主要的控件和…...

网站文章怎么做才能被收录/长春seo排名公司

DB : 11.2.0.3.0Oracle DBLINK 创建分为private 和 public dblink&#xff0c;默认创建的为private ; private dblink 只有创建的schema才能删除,sys也删除不了&#xff1b;public dblink 任意schema都可以删除,只要权限够。一、PRIVATE DBLINK:收回dba权限&#xff1a;SQL>…...

wordpress 幻灯片/新浪博客

我们大家都知道,JS有个很经典的浮点运算精度丢失问题,今天我们就来聊一聊这个问题产生的原因,以及该如何去解决它呢? 先来看下面的代码,0.10.2的结果不等于0.3,这是不是超出了我们之前的认知呢?毕竟0.10.20.3可是我们小学就已经学会了的东西,到这里怎么就不一样了呢? 0.1 …...