推流项目的ffmpeg配置和流程重点总结一下

        

        ffmpeg的初始化配置,在合成工作都是根据这个ffmpeg的配置来做的,是和成ts流还是flv,是推动远端还是保存到本地, FFmpeg 的核心数据结构,负责协调编码、封装和写入操作。它相当于推流的“总指挥”。

        先来看一下ffmpeg的推流器配置。


typedef struct
{AVStream *stream;    // 输出流AVCodecContext *enc; // 编码器int64_t next_timestamp; //下一个时间戳int samples_count;     // 采样数AVPacket *packet;   // 编码数据包
} OutputStream;typedef struct
{unsigned int config_id; //用与多路码流int protocol_type; //流媒体TYPEchar network_addr[NETWORK_ADDR_LENGTH];//流媒体地址enum AVCodecID video_codec; //视频编码器IDenum AVCodecID audio_codec; //音频编码器IDOutputStream video_stream; //VIDEO的STREAM配置OutputStream audio_stream; //AUDIO的STREAM配置AVFormatContext *oc; //是存储音视频封装格式中包含的信息的结构体,也是FFmpeg中统领全局的结构体,对文件的封装、编码操作从这里开始。
} RKMEDIA_FFMPEG_CONFIG; //FFMPEG配置

        定义了我们流媒体的地址,和复合流是ts/flv等等。 

        在使用 FFmpeg 实现推流的过程中,每个步骤都有其特定的作用,这些步骤是基于音视频处理和网络传输的基本原理设计的。以下是对每个主要步骤的详细解释,以及它们为什么必不可少:

1. 初始化网络模块 (avformat_network_init)

        作用: 初始化 FFmpeg 的网络功能,支持像 RTMP、HTTP 这样的网络协议。

        为什么需要: FFmpeg 默认不加载网络相关模块,此步骤启用网络支持,确保推流到远程服务器(如 RTMP 服务器)时能够正确建立连接。如果不初始化,推流会因为缺少网络协议支持而失败。

        原理: FFmpeg 的网络功能依赖底层库(如 librtmp 或内置的 TCP/UDP 实现),初始化会加载这些模块并注册相关协议。



2. 分配输出格式上下文 (avformat_alloc_output_context2)

    //FLV_PROTOCOL is RTMP TCPif (ffmpeg_config->protocol_type == FLV_PROTOCOL){//初始化一个FLV的AVFormatContextret = avformat_alloc_output_context2(&ffmpeg_config->oc, NULL, "flv", ffmpeg_config->network_addr); if (ret < 0){return -1;}}//TS_PROTOCOL is SRT UDP RTSPelse if (ffmpeg_config->protocol_type == TS_PROTOCOL){//初始化一个TS的AVFormatContextret = avformat_alloc_output_context2(&ffmpeg_config->oc, NULL, "mpegts", ffmpeg_config->network_addr);if (ret < 0){return -1;}}

        作用: 创建一个用于输出的容器对象(AVFormatContext),并指定输出格式(FLV/)。

        为什么需要: 推流需要将音视频数据封装成某种格式(比如 FLV 是 RTMP 的常用容器格式),这个上下文对象管理流的元数据、格式信息和输出目标。如果没有这个对象,FFmpeg 无法知道数据要以什么形式输出到哪里。
        原理: 输出格式上下文是 FFmpeg 的核心数据结构,负责协调编码、封装和写入操作。它相当于推流的“总指挥”。


3. 创建输出流 (avformat_new_stream)

    //是否指定了视频编解码器。if (fmt->video_codec != AV_CODEC_ID_NONE){// 添加一个流(如视频流或音频流),并为其分配编码参数。ret = add_stream(&ffmpeg_config->video_stream, ffmpeg_config->oc, &video_codec, fmt->video_codec);if (ret < 0){avcodec_free_context(&ffmpeg_config->video_stream.enc);free_stream(ffmpeg_config->oc, &ffmpeg_config->video_stream);avformat_free_context(ffmpeg_config->oc);return -1;}ret = open_video(ffmpeg_config->oc, video_codec, &ffmpeg_config->video_stream, NULL);if (ret < 0){avformat_free_context(ffmpeg_config->oc);}}//是否指定了音频编解码器。if (fmt->audio_codec != AV_CODEC_ID_NONE){//添加一路视频流ret = add_stream(&ffmpeg_config->audio_stream, ffmpeg_config->oc, &audio_codec, fmt->audio_codec);if (ret < 0){avcodec_free_context(&ffmpeg_config->audio_stream.enc);free_stream(ffmpeg_config->oc, &ffmpeg_config->audio_stream);avformat_free_context(ffmpeg_config->oc);return -1;}ret = open_audio(ffmpeg_config->oc, audio_codec, &ffmpeg_config->audio_stream, NULL);if (ret < 0){avformat_free_context(ffmpeg_config->oc);}}

         作用: 在输出格式上下文中添加一个流(如视频流或音频流),并为其分配编码参数。

        为什么需要: 推流通常包含视频和音频两种数据,每种数据需要独立的流来承载。创建流是为了定义这些数据的结构(如分辨率、帧率、采样率等),否则 FFmpeg 无法组织数据。

        原理: 流(AVStream)是容器中的独立轨道,推流时服务器和客户端会根据流信息解码数据

4. 打开输出 URL (avio_open)

   if (!(fmt->flags & AVFMT_NOFILE)){//第四步:打开输出文件/*** 作用: * 建立与目标服务器(如 RTMP 服务器)的物理连接。* 为什么需要: * 推流是将数据发送到远程服务器的过程,必须先打开一个通道(类似于文件句柄或网络 socket),* 否则数据无法传输。如果没有这一步,程序会因为找不到输出目标而报错。* 原理: * avio_open 使用底层 I/O 抽象层(AVIOContext)与服务器通信,支持多种协议(如 RTMP、HLS)。* 对于 RTMP,它会通过 librtmp 初始化连接并完成握手。*/ret = avio_open(&ffmpeg_config->oc->pb, ffmpeg_config->network_addr, AVIO_FLAG_WRITE);if (ret < 0){free_stream(ffmpeg_config->oc, &ffmpeg_config->video_stream);free_stream(ffmpeg_config->oc, &ffmpeg_config->audio_stream);avformat_free_context(ffmpeg_config->oc);return -1;}}

        作用: 建立与目标服务器(如 RTMP 服务器)的物理连接。

        为什么需要: 推流是将数据发送到远程服务器的过程,必须先打开一个通道(类似于文件句柄或网络 socket),否则数据无法传输。如果没有这一步,程序会因为找不到输出目标而报错

        原理: avio_open 使用底层 I/O 抽象层(AVIOContext)与服务器通信,支持多种协议(如 RTMP、HLS)。对于 RTMP,它会通过 librtmp 初始化连接并完成握手


 

5. 写入流头部信息 (avformat_write_header)

    // 第五步:写入文件头信息//这行代码会根据ffmpeg_config->oc中指定的输出格式(如FLV或TS),//生成并写入相应的头部信息到输出文件或流中。avformat_write_header(ffmpeg_config->oc, NULL);

        作用: 将流的元数据(比如编码格式、分辨率、时长等)写入输出流的开头。

        为什么需要: 接收端(比如直播服务器或播放器)需要这些信息来正确解析后续的数据。如果缺少头部信息,接收端可能无法识别流格式,导致播放失败。

        原理: 头部信息是容器格式(如 FLV)的标准部分,包含流的描述性数据,类似于文件的“索引”。 


6. 写入数据 (av_interleaved_write_frame)

int write_ffmpeg_avpacket(AVFormatContext *fmt_ctx, const AVRational *time_base, AVStream *st, AVPacket *pkt)
{/*将输出数据包时间戳值从编解码器重新调整为流时基 */av_packet_rescale_ts(pkt, *time_base, st->time_base);pkt->stream_index = st->index;/*** 第六步:写入数据 * 作用: * 将编码后的音视频数据(AVPacket)写入输出流,发送到服务器。* 为什么需要: * 这是推流的核心步骤,所有的音视频内容都通过这一步传输到目标。* 如果没有这一步,之前的准备工作就毫无意义,因为数据没有实际发送。* 原理: * FFmpeg 使用“交错写入”(interleaved)方式处理多路流(如视频和音频),确保时间戳对齐,符合实时传输的要求。* 数据会被封装为 FLV 标签(Tag)并通过网络发送。*/return av_interleaved_write_frame(fmt_ctx, pkt);
}

        作用: 将编码后的音视频数据(AVPacket)写入输出流,发送到服务器。

        为什么需要: 这是推流的核心步骤,所有的音视频内容都通过这一步传输到目标。如果没有这一步,之前的准备工作就毫无意义,因为数据没有实际发送。

        原理: FFmpeg 使用“交错写入”(interleaved)方式处理多路流(如视频和音频),确保时间戳对齐,符合实时传输的要求。数据会被封装为 FLV 标签(Tag)并通过网络发送。



7. 写入流尾部 (av_write_trailer)

    //第7步: 写入流尾部 (av_write_trailer)/*** * 作用: 标记流的结束,并写入必要的结尾信息*/av_write_trailer(ffmpeg_config.oc); // 写入AVFormatContext的尾巴

        作用: 标记流的结束,并写入必要的结尾信息。

        为什么需要: 某些容器格式需要在结束时添加元数据(如索引表),以确保接收端能正确处理整个流。如果不写入尾部,流可能会出现不完整或无法播放的问题。

        原理: 尾部信息是容器格式规范的一部分,对于 FLV 来说,它可能只是简单地关闭流,但对于其他格式(如 MP4),它可能包含关键的索引。


8. 清理资源 (avio_closep, avformat_free_context)

   //第八步:清理资源 (avio_closep, avformat_free_context)/*** * 作用: 关闭网络连接并释放内存*/free_stream(ffmpeg_config.oc, &ffmpeg_config.video_stream); // 释放VIDEO_STREAM的资源free_stream(ffmpeg_config.oc, &ffmpeg_config.audio_stream); // 释放AUDIO_STREAM的资源avio_closep(&ffmpeg_config.oc->pb);                         // 释放AVIO资源avformat_free_context(ffmpeg_config.oc);                    // 释放AVFormatContext资源

        作用: 关闭网络连接并释放内存。
        为什么需要: 推流结束后,如果不清理资源,会导致内存泄漏或网络连接未正确关闭,影响程序稳定性。对于长时间运行的推流任务尤其重要。
        原理: FFmpeg 的上下文对象和 I/O 句柄占用系统资源(如内存和 socket),需要显式释放以遵循良好的编程实践。


整体工作流程的意义,这些步骤共同构成了 FFmpeg 推流的完整工作流,反映了音视频处理和网络传输的本质:

    1.    准备阶段: 初始化环境、定义格式和目标(步骤 1-3)。
    2.    连接阶段: 建立与服务器的通信(步骤 4)。
    3.    传输阶段: 发送元数据和实际数据(步骤 5-6)。
    4.    结束阶段: 完成传输并清理(步骤 7-8)。

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

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

相关文章

大语言模型从理论到实践(第二版)-学习笔记(绪论)

大语言模型的基本概念 1.理解语言是人工智能算法获取知识的前提 2.语言模型的目标就是对自然语言的概率分布建模 3.词汇表 V 上的语言模型&#xff0c;由函数 P(w1w2 wm) 表示&#xff0c;可以形式化地构建为词序列 w1w2 wm 的概率分布&#xff0c;表示词序列 w1w2 wm…

strace工具的交叉编译

1、下载源码 git clone https://github.com/strace/strace.git cd strace 2、运行 bootstrap 脚本&#xff08;如果需要&#xff09; 如果源码中没有 configure 脚本&#xff0c;运行以下命令生成&#xff1a; ./bootstrap 3. 配置编译参数 运行 configure 脚本&#xff…

Vue 3 组件库持续集成 (CI) 实战:GitHub Actions 自动化测试与 Storybook 文档构建 - 构建高效可靠的组件库 CI 流程

引言 欢迎再次回到 Vue 3 + 现代前端工程化 系列技术博客! 在昨天的第十篇博客中,我们深入学习了代码覆盖率分析,掌握了利用 Jest 代码覆盖率报告提升单元测试有效性的方法,进一步巩固了组件库的质量防线。 今天,我们将迈向 自动化流程 的构建,聚焦于 持续集成 (Continu…

无穿戴动捕数字人互动方案 | 畅享零束缚、高沉浸的虚实交互体验

在数字化浪潮席卷而来的当下&#xff0c;虚拟人互动体验正逐渐成为各领域的新宠。长久以来&#xff0c;虚拟人驱动主要依靠穿戴式动作捕捉设备&#xff0c;用户需要通过佩戴传感器或标记点来实现动作捕捉。然而&#xff0c;随着技术的不断突破&#xff0c;一种全新的无穿戴动作…

03 HarmonyOS Next仪表盘案例详解(二):进阶篇

温馨提示&#xff1a;本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦&#xff01; 文章目录 前言1. 响应式设计1.1 屏幕适配1.2 弹性布局 2. 数据展示与交互2.1 数据卡片渲染2.2 图表区域 3. 事件处理机制3.1 点击事件处理3.2 手势…

python-leetcode-统计构造好字符串的方案数

2466. 统计构造好字符串的方案数 - 力扣&#xff08;LeetCode&#xff09; 这个问题可以用**动态规划&#xff08;DP&#xff09;**来解决&#xff0c;思路如下&#xff1a; 思路 1. 定义 DP 数组 设 dp[i] 表示长度为 i 的好字符串的个数。 2. 状态转移方程 我们可以在 dp…

MySQL------存储引擎和用户和授权

9.存储引擎 1.两种引擎 MyISAM和InnoDB 2.两种区别 1.事务&#xff1a; MyISAM不支持事务 2.存储文件: innodb : frm、ibd MyISAM: frm、MYD、MYI 3.数据行锁定: MyISAM不支持 4.全文索引: INNODB不支持&#xff0c;所以MYISAM做select操作速度很快 5.外键约束: MyISAM…

题海拾贝:P9241 [蓝桥杯 2023 省 B] 飞机降落

Hello大家好&#xff01;很高兴我们又见面啦&#xff01;给生活添点passion&#xff0c;开始今天的编程之路&#xff01; 我的博客&#xff1a;<但凡. 我的专栏&#xff1a;《编程之路》、《数据结构与算法之美》、《题海拾贝》 欢迎点赞&#xff0c;关注&#xff01; 1、题…

删除有序数组中的重复项(js实现,LeetCode:26)

给你一个 非严格递增排列 的数组 nums &#xff0c;请你原地删除重复出现的元素&#xff0c;使每个元素只出现一次&#xff0c;返回删除后数组的新长度。元素的相对顺序应该保持一致。然后返回 nums 中唯一元素的个数。 考虑 nums 的唯一元素的数量为 k &#xff0c;你需要做以…

3-9 WPS JS宏单元格复制、重定位应用(拆分单表到多表)

************************************************************************************************************** 点击进入 -我要自学网-国内领先的专业视频教程学习网站 *******************************************************************************************…

大白话react第十六章React 与 WebGL 结合的实战项目

大白话react第十六章React 与 WebGL 结合的实战项目 1. 项目简介 React 是一个构建用户界面的强大库&#xff0c;而 WebGL 则允许我们在网页上实现高性能的 3D 图形渲染。将它们结合起来&#xff0c;我们可以创建出炫酷的 3D 网页应用&#xff0c;比如 3D 产品展示、虚拟场景…

【AI赋能】AI 工具生成视频教材:从创意到成品的全流程指南

AI 工具生成视频教材&#xff1a;从创意到成品的全流程指南 目标 通过本教材&#xff0c;您将学会如何利用 AI 工具&#xff08;Grok、Sora、Speechify 和 CapCut&#xff09;生成一个完整的视频&#xff0c;包括脚本生成、视频片段制作、字幕添加、音频生成以及最终剪辑合成…

C/C++蓝桥杯算法真题打卡(Day2)

一、面试题 08.01. 三步问题 - 力扣&#xff08;LeetCode&#xff09; 算法代码&#xff1a; class Solution { public:const int MOD 1e9 7;int waysToStep(int n) {// 1. 创建 dp 表// 2. 初始化// 3. 填表// 4. 返回// 处理边界情况if (n 1 || n 2)return n;if (n 3)r…

腾讯云物联网平台(IoT Explorer)设备端使用

1、直接看图流程 2、跑起来demo,修改产品id,设备名称,设备秘钥。 3、连接部分 4、修改默认地址和端口 sdk里面的地址默认是带着产品ID拼接的,咱们现在中铁没有泛域名解析,要改下这里。把+productID都去掉,然后地址里的.也去掉。

GStreamer —— 2.13、Windows下Qt加载GStreamer库后运行 - “教程13:播放控制“(附:完整源码)

运行效果(音频) 简介 上一个教程演示了GStreamer工具。本教程介绍视频播放控制。快进、反向播放和慢动作都是技术 统称为 Trick Modes&#xff0c;它们都有一个共同点 修改 Normal playback rate。本教程介绍如何实现 这些效果并在交易中添加了帧步进。特别是&#xff0c;它 显…

Dify+DeepSeek | Excel数据一键可视化(创建步骤案例)(echarts助手.yml)(文档表格转图表、根据表格绘制图表、Excel绘制图表)

Dify部署参考&#xff1a;Dify Rag部署并集成在线Deepseek教程&#xff08;Windows、部署Rag、安装Ragan安装、安装Dify安装、安装ollama安装&#xff09; DifyDeepSeek - Excel数据一键可视化&#xff08;创建步骤案例&#xff09;-DSL工程文件&#xff08;可直接导入&#x…

vscode mac版本 配置git

首先使用 type -a git查看git的安装目录 然后在vscode中找到settings配置文件&#xff0c;修改git.path

JVM与性能调优详解

以下是关于 JVM与性能调优 的详细解析&#xff0c;结合理论、实践及常见问题&#xff0c;分多个维度展开&#xff1a; 一、JVM性能调优的核心目标 性能调优的核心目标是通过优化内存管理、垃圾回收&#xff08;GC&#xff09;策略和线程管理&#xff0c;实现以下平衡&#xff…

Vue23Web 基礎性拉滿的面試題(2025版)還沒更新完...

Vue2&3 基礎性1. 關於Vue2和Vue3生命週期的差別2. Vue2&3組件之間傳參不同點Vue2 傳遞與接收Vue3 傳遞與接收 (使用script setup語法糖)Vue3 傳遞與接收 (不使用script setup語法糖) 3. Vue2&3 keep-alive 組件Vue2 keep-aliveVue3 keep-alive 進階性爲什麽POST請求…

基于SpringBoot实现旅游酒店平台功能一

一、前言介绍&#xff1a; 1.1 项目摘要 随着社会的快速发展和人民生活水平的不断提高&#xff0c;旅游已经成为人们休闲娱乐的重要方式之一。人们越来越注重生活的品质和精神文化的追求&#xff0c;旅游需求呈现出爆发式增长。这种增长不仅体现在旅游人数的增加上&#xff0…