第5课 使用FFmpeg将rtmp流再转推到rtmp服务器

本课对应源文件下载链接:

https://download.csdn.net/download/XiBuQiuChong/88801992

 通过前面的学习,我们已经可以正常播放网络rtmp流及本地mp4文件。这节课,我们将在前面的基础上实现一个常用的转推功能:读取rtmp流或mp4文件并转推到rtmp服务器上实现直播转发功能。

一、最终实现的效果

上面左图为播放的rtmp流并将该流转推到另一台rtmp服务器,右图为用vlc播放的另一台rtmp服务器上被转发的流。

二、使用FFmpeg将rtmp流转推到另一台rtmp服务器​的原理

使用FFmpeg API 转码推流的一般过程如下:

1.引入ffmpeg库:在代码中引入ffmpeg库,以便使用其提供的功能。

2.打开输入文件:使用avformat_open_input()函数打开输入文件,并获取输入文件的相关信息。

3.查找流信息:使用avformat_find_stream_info()函数查找输入文件中的流信息,并将其存储在AVFormatContext结构体中。

4.创建输出上下文:使用avformat_alloc_output_context2()函数创建输出上下文,并设置输出格式。

5.添加输出流:根据输入文件的流信息,使用avformat_new_stream()函数创建输出流,并将其添加到输出上下文中。

6.设置编码参数:为输出流设置编码参数,包括编码器、编码器参数等。

7.输出文件:使用avio_open()函数打开输出文件,并将输出文件的相关信息存储在输出上下文中。

8.写入文件头:使用avformat_write_header()函数写入输出文件的文件头。

9.转码推流:循环读取输入文件的数据包,使用av_read_frame()函数读取数据包,然后使用avcodec_send_frame()函数发送数据包给编码器进行编码,再使用avcodec_receive_packet()函数接收编码后的数据包,最后使用av_interleaved_write_frame()函数将编码后的数据包写入输出流。

10.写入文件尾:使用av_write_trailer()函数写入输出文件的文件尾。

11.释放资源:释放所有的上下文、流和其他资源,使用avformat_close_input()函数关闭输入文件。

三、转推功能的具体实现

与rtmp流或mp4文件播放功能相比,转推功能只是在原来的基础上又增加了编码功能和向rtmp服务器的推送功能。为了降低难度,这节课的转推功能不涉及编码部分,只实现将拉取来的rtmp流直接进行转推。

1.为了与上节课的播放功能区分,新建或直接复制fmlp(Flash Media Live Player)类为一个新的fmlt(Flash Media Live Transcoder)类,并修改主对话框相应代码使fmlt能正常工作并实现正常的播放功能。

修改如下:

//#include "fmlp.h"
#include "fmlt.h"
………………
//fmlp *myFmlp = new fmlp();
fmlt *myFmlt = new fmlt();

2.与mp4文件相比,rtmp流转推实现起来相对容易,因此,我们先在原来的基础上实现rtmp流的转推功能。

(1)直接拷贝原fmlp.cpp的代码到fmt.cpp中,并定义转推到另一台rtmp服务器的流地址等变量:

//转码输出初始化	
	const char *outFileName = "rtmp://192.168.0.101/hk/cctv";		
	AVOutputFormat *outFormat = NULL;
	AVFormatContext *outFormatCtx = NULL;
	//定义输出音视频流
	AVStream *videoStream = NULL;
	AVStream *audioStream = NULL;

(2)打开输出流:

avformat_alloc_output_context2(&outFormatCtx, NULL, "flv", outFileName);

………………

         videoStream = avformat_new_stream(outFormatCtx, vDecodec);

         videoStream->id = outFormatCtx->nb_streams - 1;

         videoStream->codecpar->codec_tag = 0;

         avcodec_parameters_from_context(videoStream->codecpar, vDecodeCtx);

         audioStream = avformat_new_stream(outFormatCtx, aDecodec);

         audioStream->codecpar->codec_tag = 0;

         audioStream->id = outFormatCtx->nb_streams - 1;

         avcodec_parameters_from_context(audioStream->codecpar, aDecodeCtx);

         av_dump_format(outFormatCtx, 0, outFileName, 1);

         ret = avio_open2(&outFormatCtx->pb, outFileName, AVIO_FLAG_READ_WRITE, nullptr, nullptr);

         if (ret < 0){

                  return -1;

         }

         ret = avformat_write_header(outFormatCtx, NULL);

         if (ret < 0){

                  TRACE("ret:%d\n", ret);

                  return -1;

         }

(3)获取到原rtmp流并正常播放音视频后,将音视频包直接写入输出流:

if (normalPkt.stream_index == videoIndex) {

                          //原视频播放代码

                          normalPkt.stream_index = videoStream->index;

                          normalPkt.pts = currentTime;

                          normalPkt.dts = currentTime;

                          normalPkt.duration = currentTime;

                          normalPkt.pos = -1;

                          //enVideoPacket.flags = AV_PKT_FLAG_KEY;

                          if (normalPkt.size > 0){

                                   ret = av_interleaved_write_frame(outFormatCtx, &normalPkt);

                          }

                          av_packet_unref(&normalPkt);

                  }

                  else if (normalPkt.stream_index == audioIndex)

                  {                       

                          //原音频播放代码

                          normalPkt.stream_index = audioStream->index;

                          normalPkt.pts = currentTime;

                          normalPkt.dts = currentTime;

                          normalPkt.duration = currentTime;

                          normalPkt.pos = -1;

                          //enVideoPacket.flags = AV_PKT_FLAG_KEY;

                          if (normalPkt.size > 0){

                                   ret = av_interleaved_write_frame(outFormatCtx, &normalPkt);

                          }

                          av_packet_unref(&normalPkt);

          }

这样,就实现了在播放音视频的同时又能将该流转推到另一台服务器的功能。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

移动云ONAIR媒体云全解读!媒体内容数字化融合一站式解决方案

当下&#xff0c;传统媒体面临着诸多挑战&#xff0c;如何利用信息技术提升内容的质量、形式和分发效率&#xff0c;成为媒体行业的迫切需求。移动云作为数字中国建设的“主力军”&#xff0c; 立足于新兴媒体与云计算市场的变化与需求&#xff0c;推出了ONAIR 媒体云解决方案&…

计算机设计大赛 深度学习+opencv+python实现车道线检测 - 自动驾驶

文章目录 0 前言1 课题背景2 实现效果3 卷积神经网络3.1卷积层3.2 池化层3.3 激活函数&#xff1a;3.4 全连接层3.5 使用tensorflow中keras模块实现卷积神经网络 4 YOLOV56 数据集处理7 模型训练8 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &am…

C++之强制转换

目录 static_cast const_cast 思维导图 类型转换有c风格的&#xff0c;当然还有c风格的。c风格的转换的格式很简单 TYPE a &#xff08;TYPE&#xff09;EXPRESSION; 但是c风格的类型转换有不少的缺点&#xff0c;有的时候用c风格的转换是不合适的&#xff0c;因为它可以在…

【复现】智慧园区综合管理平台文件上传漏洞_40

目录 一.概述 二 .漏洞影响 三.漏洞复现 1. 漏洞一&#xff1a; 四.修复建议&#xff1a; 五. 搜索语法&#xff1a; 六.免责声明 一.概述 智慧园区管理平台基于GISBIM的云平台数据中心和物联网技术为核心&#xff0c;将各项基础设施连接成一个有机的整体&#xff0c;通…

Vector CANdb++ Editor和CANdb++ Admin的区别

目录 1 CANdb Editor和CANdb Admin的功能偏差 2 CANdb Program窗口 3 下载并安装CANdb Editor和CANdb Admin 3.1 安装CANdb Admin.J1939 3.0 SP27 优质博文推荐阅读&#xff08;单击下方链接&#xff0c;即可跳转&#xff09;&#xff1a; Vector工具链 CAN Matrix DBC …

[Vue3]父子组件相互传值数据同步

简介 vue3中使用setup语法糖&#xff0c;父子组件之间相互传递数据及数据同步问题 文章目录 简介父传子props传递值 使用v-bind绑定props需要计算toRefcomputed emit传递方法 使用v-on绑定 子传父expose v-model总结 父传子 props传递值 使用v-bind绑定 父组件通过props给子…

代码生成器(新):mybatis-plus-generator使用指南

代码生成器&#xff08;新&#xff09;官网 后端代码&#xff1a;点击查看 LearnElementUiAndSpringBoot 提醒&#xff1a;LearnElementUiAndSpringBoot下载完后&#xff0c;在运行调试 Main.java里的main方法之前&#xff0c;除了utils包和Main.java文件&#xff0c;其他包需…

机器学习逻辑回归模型训练与超参数调优 ##3

文章目录 [TOC]基于Kaggle电信用户流失案例数据&#xff08;可在官网进行下载&#xff09;逻辑回归模型训练逻辑回归的超参数调优 基于Kaggle电信用户流失案例数据&#xff08;可在官网进行下载&#xff09; 数据预处理部分可见&#xff1a; 机器学习数据预处理方法&#xff0…

共享网盘系统PHP源码

新V5.0版本&#xff0c;支持上传视频、支持视频播放、支持共享&#xff0c;也可以自己用。 可以自动生成视频外链&#xff0c;下载地址&#xff0c;播放器代码&#xff0c;html代码&#xff0c;ubb代码等等。 使用方法&#xff1a; 源码上传到服务器&#xff0c;打开网站根据…

【自定义序列化器】⭐️通过继承JsonSerializer和实现WebMvcConfigurer类完成自定义序列化

目录 前言 解决方案 具体实现 一、自定义序列化器 二、两种方式指定作用域 1、注解 JsonSerialize() 2、实现自定义全局配置 WebMvcConfigurer 三、拓展 WebMvcConfigurer接口 章末 前言 小伙伴们大家好&#xff0c;上次做了自定义对象属性拷贝&#x…

LLM之RAG实战(二十三)| LlamaIndex高级检索(二):父文档检索

在上一篇文章中&#xff0c;我们介绍了基本RAG的构建&#xff0c;也探讨了RAG管道中从小到大检索技术的两种主要技术&#xff1a;父文档检索和句子窗口检索。 在本文&#xff0c;我们将深入探讨一下从小到大检索技术中的父文档检索。 一、块引用&#xff1a;较小的子块引用较大…

css浮动

CSS浮动 1. 浮动的简介 在最初&#xff0c;浮动是用来实现文字环绕图片效果的&#xff0c;现在浮动是主流的页面布局方式之一。 2. 元素浮动后的特点 脱离文档流。不管浮动前是什么元素&#xff0c;浮动后&#xff1a;默认宽与高都是被内容撑开&#xff08;尽可能小&#x…

AI专题:冬渐去、春将来,待看,AI 开花,数据挂果,可控链潮起

今天分享的是AI 系列深度研究报告&#xff1a;《AI专题&#xff1a;冬渐去、春将来&#xff0c;待看&#xff0c;AI 开花&#xff0c;数据挂果&#xff0c;可控链潮起》。 &#xff08;报告出品方&#xff1a;AVIC&#xff09; 报告共计&#xff1a;36页 行业概览:2023年呈稳…

哪种安全数据交换系统,可以满足信创环境要求?

安全数据交换系统是一种专门设计用于在不同网络环境之间安全传输数据的技术解决方案。这类系统确保数据在传输过程中的完整性、机密性和可用性&#xff0c;同时遵守相关的数据保护法规和行业标准。 使用安全数据交换系统的原因主要包括以下几点&#xff1a; 1、数据保护&#…

光隔离探头

一、前言。 光隔离探头的CMRR比高压差分探头要高很多,在一些共模电压较高的测量领域用的比较多,如:开关电源、逆变器等。但是市面上介绍光隔离探头的方案比较少,这里简要说明一下我的个人想法。 二、数字光和模拟光。 数字光就是通信上常用的光模块,传的是数字信号,带…

【学网络安全】kali linux入门及常用简单工具介绍(附工具包)

前言 相信很多同学了解到和学习网络安全的时候都听过kali系统&#xff0c;大家都称之为黑客最喜爱的系统&#xff0c;那么什么是kali&#xff0c;初学者用kali能做些什么&#xff0c;我将在本文中做简单的介绍 一、kali linux是什么&#xff1f; Kali Linux 是专门用于渗透测…

linux服务器springboot或tomcat项目启动,进行jvm参数调优设置

简介 在实验环境或生产环境中&#xff0c;往往一台linux服务器需要添加启动n个项目&#xff0c;但是项目启动占用的jvm内存默认值基本上都是很大的&#xff0c;800m到2G都有&#xff0c;这样很容易将服务器的内存吃垮&#xff0c;从而导致系统强制oom&#xff08;内存泄露&…

(7)医学图像配准综述:SimpleITK + SimpleElastix + Elastix + ITKElastix + PyElastix

文章目录 前言一、常见的图像配准工具1.0、ITK VTK —— 科学界最大与最早的开源免费项目之一1.1、ITK系列&#xff1a;ITK SimpleITK SimpleElastix1.2、Elastix系列&#xff1a;Elastix ITKElastix PyElastix 二、图像配准2.1、SimpleITK图像配准2.2、SimpleElastix图像…

ROS从入门到精通4-1:Docker安装与常用命令总结

目录 0 专栏介绍1 Docker与机器人应用2 Docker安装步骤3 Docker常用命令3.1 创建与启动容器3.2 暂停与删除容器3.3 容器文件拷贝3.4 构建镜像与上下文 0 专栏介绍 本专栏旨在通过对ROS的系统学习&#xff0c;掌握ROS底层基本分布式原理&#xff0c;并具有机器人建模和应用ROS进…

(2021|ICLR,LoRA,秩分解矩阵,更少的可训练参数)LoRA:大语言模型的低秩自适应

LoRA: Low-Rank Adaptation of Large Language Models 公和众和号&#xff1a;EDPJ&#xff08;进 Q 交流群&#xff1a;922230617 或加 VX&#xff1a;CV_EDPJ 进 V 交流群&#xff09; 目录 0. 摘要 2. 问题陈述 3. 现有的解决方案不够好吗&#xff1f; 4. 我们的方法 …