FFmpeg实现rtp推流

以下是一个简单的示例代码,演示了如何使用 UDP 或 TCP 进行音视频传输:
代码未经验证,供参考

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <libavformat/avformat.h>#define RTPPKT_LEN 1400
#define IPOUT_PAYNUM 1// UDP Socket
int udpSocket;// TCP Socket
int tcpSocket;// UDP 发送函数
int udp_write_buffer(void* opaque, uint8_t* buf, int buf_size) {struct sockaddr_in destAddr;memset(&destAddr, 0, sizeof(destAddr));destAddr.sin_family = AF_INET;destAddr.sin_port = htons(1234); // 设置目标端口号destAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); // 设置目标IP地址ssize_t sentBytes = sendto(udpSocket, buf, buf_size, 0, (struct sockaddr*)&destAddr, sizeof(destAddr));if (sentBytes < 0) {perror("UDP 发送失败");return -1;}return 0;
}// TCP 发送函数
int tcp_write_buffer(void* opaque, uint8_t* buf, int buf_size) {ssize_t sentBytes = send(tcpSocket, buf, buf_size, 0);if (sentBytes < 0) {perror("TCP 发送失败");return -1;}return 0;
}int main() {av_register_all();avformat_network_init();// 创建输入格式上下文AVFormatContext* inputFormatCtx = avformat_alloc_context();// 打开输入文件或网络流const char* inputUrl = "input.mp4";int ret = avformat_open_input(&inputFormatCtx, inputUrl, nullptr, nullptr);if (ret != 0) {printf("无法打开输入文件:%s\n", inputUrl);return -1;}// 获取流信息ret = avformat_find_stream_info(inputFormatCtx, nullptr);if (ret < 0) {printf("无法获取流信息\n");return -1;}// 寻找视频流索引int videoStreamIndex = -1;for (unsigned int i = 0; i < inputFormatCtx->nb_streams; i++) {if (inputFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {videoStreamIndex = i;break;}}// 创建输出格式上下文AVFormatContext* outputFormatCtx = nullptr;ret = avformat_alloc_output_context2(&outputFormatCtx, nullptr, "rtp", "rtp://127.0.0.1:1234"); // 设置输出 URLif (ret < 0) {printf("无法创建输出格式上下文\n");return -1;}// 创建 AVIO 缓存空间unsigned char* outBuffer = (unsigned char*)av_malloc(RTPPKT_LEN * IPOUT_PAYNUM);// 创建 UDP SocketudpSocket = socket(AF_INET, SOCK_DGRAM, 0);if (udpSocket < 0) {perror("无法创建 UDP Socket");return -1;}// 创建 TCP SockettcpSocket = socket(AF_INET, SOCK_STREAM, 0);if (tcpSocket < 0) {perror("无法创建 TCP Socket");return -1;}// 创建 AVIO 上下文AVIOContext* avioOut;if (strcmp("UDP", "RTP/AVP") == 0) {avioOut = avio_alloc_context(outBuffer, RTPPKT_LEN * IPOUT_PAYNUM, 1, nullptr, nullptr, udp_write_buffer, nullptr);} else if (strcmp("TCP", "RTP/AVP") == 0) {avioOut = avio_alloc_context(outBuffer, RTPPKT_LEN * IPOUT_PAYNUM, 1, nullptr, nullptr, tcp_write_buffer, nullptr);}if (!avioOut) {printf("无法创建 AVIO 上下文\n");return -1;}avioOut->max_packet_size = RTPPKT_LEN;outputFormatCtx->pb = avioOut;outputFormatCtx->flags = AVFMT_FLAG_CUSTOM_IO;// 复制视频流参数到输出格式上下文AVStream* outputStream = avformat_new_stream(outputFormatCtx, nullptr);ret = avcodec_parameters_copy(outputStream->codecpar, inputFormatCtx->streams[videoStreamIndex]->codecpar);if (ret < 0) {printf("无法复制视频流参数\n");return -1;}// 写入输出头部ret = avformat_write_header(outputFormatCtx, nullptr);if (ret < 0) {printf("无法写入输出头部\n");return -1;}// 开始读取和发送数据包AVPacket packet;while (av_read_frame(inputFormatCtx, &packet) >= 0) {if (packet.stream_index == videoStreamIndex) {// 发送数据包到输出上下文ret = av_interleaved_write_frame(outputFormatCtx, &packet);if (ret < 0) {printf("无法发送数据包\n");return -1;}}av_packet_unref(&packet);}// 写入输出尾部ret = av_write_trailer(outputFormatCtx);if (ret < 0) {printf("无法写入输出尾部\n");return -1;}// 关闭 Socketclose(udpSocket);close(tcpSocket);// 释放资源avformat_close_input(&inputFormatCtx);avformat_free_context(inputFormatCtx);avformat_free_context(outputFormatCtx);avio_context_free(&avioOut);av_free(outBuffer);return 0;
}

这个示例代码基于 FFmpeg 库,演示了如何使用 UDP 或 TCP 进行音视频传输。具体的步骤包括:

  1. 注册 FFmpeg 库并初始化网络模块。
  2. 创建输入格式上下文,并打开输入文件或网络流。
  3. 获取流信息,并找到视频流索引。
  4. 创建输出格式上下文,并设置输出协议为 RTP。
  5. 创建 UDP 或 TCP Socket。
  6. 创建 AVIO 缓存空间和 AVIO 上下文,并将其赋值给输出格式上下文。
  7. 复制视频流参数到输出格式上下文。
  8. 写入输出头部。
  9. 通过循环读取输入文件的数据包,并发送到输出格式上下文。
  10. 写入输出尾部。
  11. 关闭 Socket 和释放资源。

您可以根据实际需求修改相关参数,如输入文件、目标地址、端口号等,以适配您的具体场景。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/237447.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mac设置ll永久生效,设置.bash_profile生效

Mac设置ll永久生效&#xff0c;设置.bash_profile生效 前言&#xff1a;Mac上自带的终端不好用&#xff0c;一般我推荐ITerm终端&#xff0c;官网下载即可 如果想只生效一次&#xff1a; 直接在终端执行alias llls -l即可 如果想永久生效&#xff1a; vim ~/.bash_profile&…

02 - Kbuild子系统(整理中)

1. Kbuild简介 Kernel build&#xff0c;用来编译 Linux 内核基于 GNU make 设计&#xff0c;对 Makefile 进行扩充 菜单式配置&#xff1a;Kconfig预定义目标和变量&#xff1a;xx_defconfig、menuconfig、obj-y跨平台工具、递归式 Makefile Linux 模块化设计、高度可以裁剪 …

java开发面试:常见业务场景之单点登录SSO(JWT)、权限认证、上传数据的安全性的控制、项目中遇到的问题、日志采集(ELK)、快速定位系统的瓶颈

单点登录&#xff08;SSO&#xff09; 单点登录&#xff0c;Single Sign On&#xff08;简称SSO&#xff09;,只需要登录一次&#xff0c;就可以访问所有信任的应用系统。 如果是单个tomcat服务&#xff0c;session可以共享&#xff0c;如果是多个tomcat&#xff0c;那么服务s…

tcp 的限制 (TCP_WRAPPERS)

#江南的江 #每日鸡汤&#xff1a;青春是打开了就合不上的书&#xff0c;人生是踏上了就回不了头的路&#xff0c;爱情是扔出了就收不回的赌注。 #初心和目标&#xff1a;拿到高级网络工程师 TCP_WRAPPERs Tcp_wrappers 对于七层模型中是位于第四层的安全工具&#xff0c;他…

微信小程序 动态设置状态栏样式

onLoad(options) {//修改状态栏标题wx.setNavigationBarTitle({title: 页面标题, //页面标题success: () > {}, //接口调用成功的回调函数fail: () > {}, //接口调用失败的回调函数complete: () > {} //接口调用结束的回调函数&#xff08;调用成功、失败…

[CVPR 2023:3D Gaussian Splatting:实时的神经场渲染]

文章目录 前言小结 原文地址&#xff1a;https://blog.csdn.net/qq_45752541/article/details/132854115 前言 mesh 和点是最常见的3D场景表示&#xff0c;因为它们是显式的&#xff0c;非常适合于快速的基于GPU/CUDA的栅格化。相比之下&#xff0c;最近的神经辐射场&#xf…

从0开始学Git指令

从0开始学Git指令 因为网上的git文章优劣难评&#xff0c;大部分没有实操展示&#xff0c;所以打算自己从头整理一份完整的git实战教程&#xff0c;希望对大家能够起到帮助&#xff01; 初始化一个Git仓库&#xff0c;使用git init命令。 添加文件到Git仓库&#xff0c;分两步…

Ceph基本环境配置

基本环境准备 准备三台服务器&#xff08;服务器至少需要添加两块磁盘&#xff09;以及一台客户端&#xff0c;最好配置时间同步同时再次配置hosts解析。 node1192.168.134.160node2192.168.134.161node3192.168.134.162node4192.168.134.163客户端 配置免密登录 [rootnode…

智能优化算法应用:基于金鹰算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于金鹰算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于金鹰算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.金鹰算法4.实验参数设定5.算法结果6.参考文献7.MA…

多模态大模型机器人VIMA讲解与资料整理 #持续更新

简单录制了一个视频&#xff0c;欢迎查看&#xff0c;希望对您有帮助&#xff1a; 具身智能开源工作试玩&#xff1a;VIMA_哔哩哔哩_bilibili 参考资料&#xff1a; 多模态prompt通往通用机器人操控——VIMA论文解读 - 知乎 (zhihu.com) 40. VIMA&#xff1a;基于多模态输入…

数据库学习日常案例20231221-oracle libray cache lock分析

1 问题概述&#xff1a; 阻塞的源头为两个ddl操作导致大量的libray cache lock 其中1133为gis sde的create table as语句。 其中697为alter index语句。

第二十一章网络通讯

网络程序设计基础 局域网与互联网 为了实现两台计算机的通信&#xff0c;必须用一个网络线路连接两台计算机。如下图所示 网络协议 1.IP协议 IP是Internet Protocol的简称&#xff0c;是一种网络协议。Internet 网络采用的协议是TCP/IP协议&#xff0c;其全称是Transmission…

2312llvm,05后端下

匹配模式 每个目标都有个叫<Target_Name>DAGToDAGISel的SelectionDAGISel子类.它通过实现子类的Select方法来选指. 如SPARC中的SparcDAGToDAGISel::Select()(见lib/Target/Sparc/SparcISelDAGToDAG.cpp文件).接收要匹配的SDNode参数,返回代表物理指令的SDNode值;否则出…

案例125:基于微信小程序的个人健康数据管理系统的设计与实现

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;SSM JDK版本&#xff1a;JDK1.8 数据库&#xff1a;mysql 5.7 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.5.4 小程序框架&#xff1a;uniapp 小程序开发软件&#xff1a;HBuilder X 小程序…

龙蜥开源操作系统能解决CentOS 停服造成的空缺吗?

龙蜥开源操作系统能解决CentOS 停服造成的空缺吗&#xff1f; 本文图片来源于龙蜥&#xff0c;仅做介绍时引用用途&#xff0c;版权归属龙蜥和相关设计人员。 一、《国产服务器操作系统发展报告&#xff08;2023&#xff09;》称操作系统已步入 2.0 时代&#xff0c;服务器操作…

MacOS+Homebrew+iTerm2+oh my zsh+powerlevel10k美化教程

MacOS终端 你是否已厌倦了MacOS终端的大黑屏&#xff1f; 你是否对这种美观的终端抱有兴趣&#xff1f; 那么&#xff0c;接下来我将会教你用最简单的方式来搭建一套自己的终端。 Homebrew的安装 官网地址&#xff1a;Homebrew — The Missing Package Manager for macOS (o…

Hbase的安装配置

注&#xff1a;本文默认已经完成hadoop的下载以及环境配置 1.上传zookeeper和hbase压缩包到指令路径并且解压 (理论上讲&#xff0c;hbase其实内置了zookeeper&#xff0c;我们也可以不另外下载&#xff0c;另外下载的目的在于减少组件间依赖性) cd /home mkir hbase cd /hom…

Cron表达式与实际应用场景

目录 Cron 表达式 简介 Cron 表达式 语法 分配负载 Cron 表达式 简介 Cron的历史可以追溯到UNIX操作系统的早期。Cron&#xff08;来自希腊语"chronos"&#xff0c;意为时间&#xff09;是一种用于在预定时间执行计划任务的实用程序。 起源&#xff1a; Cron最早…

泽攸科技SEM台式扫描电子显微镜

泽攸科技是一家国产的科学仪器公司&#xff0c;专注于研发、生产和销售原位电镜解决方案、扫描电镜整机、台阶仪、探针台等仪器。目前台式扫描电镜分为三个系列&#xff1a;ZEM15、ZEM18、ZEM20。 ZEM15台式扫描电镜&#xff1a; ZEM18台式扫描电镜&#xff1a; ZEM20台式扫描…

WeakMap 和 WeakSet:解决内存泄漏避免循环引用(下)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…