封装 H.264 视频为 FLV 格式然后推流

封装 H.264 视频为 FLV 格式并通过 RTMP 推流

flyfish

协议

RTMP (Real-Time Messaging Protocol)
RTSP (Real Time Streaming Protocol)
SRT (Secure Reliable Transport)
WebRTC

RTMP(Real Time Messaging Protocol)是一种用于实时音视频流传输的协议。它由Adobe公司开发,主要用于将音视频数据从客户端(如摄像头、编码器)推送到服务器(如流媒体服务器),再由服务器分发给众多观众。

封装格式:MP4、RMVB、FLV、AVI等
编码标准:H.264、MPEG-2等
视频像素数据:YUV420P、RGB、ARGB等

在这里插入图片描述

SPS和PPS

SPS (Sequence Parameter Set) - 序列参数集:
SPS包含了编码视频序列的全局参数,如图像尺寸、帧率、编码配置信息(如profile和level)、颜色空间信息等。这些参数在视频序列开始时发送,并在整个序列中保持不变,除非出现新的SPS。解码器需要这些信息来正确初始化解码过程。

PPS (Picture Parameter Set) - 图像参数集:
PPS提供了与单个图像或帧相关的参数,比如熵编码模式、去块滤波器参数等。每个PPS对应一个或多个图像,并跟随在SPS之后发送。与SPS一样,PPS在视频流中也是相对静态的,但在序列中可以改变。

封装 H.264 视频为 FLV 格式并通过 RTMP 推流步骤

1 提取 SPS 和 PPS
在处理 H.264 视频流之前,首先需要从视频数据中提取 SPS 和 PPS。这些参数通常在 H.264 数据流中的 IDR 帧(关键帧)中,可以通过解析 NAL 单元来获取。

2 封装 SPS 和 PPS 到 FLV
将提取到的 SPS 和 PPS 封装到 FLV 封装格式中。
创建一个FLV视频标签,设置其类型为视频(tag type = 9)。
将SPS和PPS组合成一个NAL单元,并在前面加上NALU头(通常是一个起始码,如0x00000001)。
将此NAL单元作为第一个视频标签的数据部分,设置适当的时间戳和帧类型标识。

3 发送
SPS 和 PPS 到 RTMP 服务器
一般情况下,在 RTMP 推流开始之前,需要先发送 SPS 和 PPS 数据给 RTMP 服务器,以告知接收端解码器关于视频流的信息。
对于每一个H.264视频帧,创建一个新的FLV视频标签。
每个视频帧也需要带有NALU头,并根据帧类型(如I帧、P帧、B帧)设置相应的帧类型标识。
设置正确的时间戳,确保视频播放的同步。

在RTMP协议中,视频数据(包括SPS、PPS、IDR帧、P帧、B帧等)被封装在FLV格式的视频标签(Video Tag)里。每个视频标签开始会有一个Header,描述了该标签的类型、数据长度和时间戳等信息,紧随其后的是实际的视频数据。这些视频数据单元(NALUs)是H.264编码的原始二进制数据

在这里插入图片描述

Frame

IDR (Instantaneous Decoding Refresh) 帧:
IDR帧是一种特殊的I帧,用于实现解码器的即时刷新。当解码器遇到IDR帧时,它会丢弃之前的所有参考帧,从IDR帧开始重新构建参考图像序列。IDR帧是解码独立的,确保了在IDR之后的视频帧不会引用IDR之前的任何帧,有利于错误恢复和随机访问。

I帧 (Intra-coded Frame):
I帧是帧内编码帧,包含了完整画面的所有信息,可以独立解码,不需要参考其他帧。它是视频序列中的关键帧,通常用于场景切换或作为错误恢复点。

P帧 (Predictive-coded Frame):
P帧是预测编码帧,它只存储相对于前一个已解码帧(通常是I帧或P帧)的变化信息。解码P帧时需要参考之前的帧,因此它依赖于过去的信息,能够实现较高的压缩效率。

B帧 (Bi-directional Predictive-coded Frame):
B帧是双向预测编码帧,它利用前后两个已解码帧(可以是I帧、P帧或B帧)的信息进行预测,能够提供更高的压缩率。B帧的解码需要依据其前后帧,因此在编码顺序和解码顺序上可能有所不同,增加了编解码的复杂性,但提高了压缩效率。

GOP

GOP是一组连续的画面,始于一个I帧(关键帧),结束于下一个I帧之前,中间包含P帧(预测帧)和B帧(双向预测帧)。I帧是完整图像,可以独立解码
在这里插入图片描述

Slice

frame是视频中完整的图像单元,而slice是帧内进一步的逻辑分块
Slice是视频编码中对一帧图像进行逻辑划分的单元。在H.264/H.265编码中,为了提高编码效率和容错能力,一帧图像可以被分割成一个或多个slice。
每个slice包含了一组连续的宏块(Macroblocks),这些宏块可以独立进行解码,而不必等待整个帧的数据到达。这样的设计使得即使在网络不稳定或数据包丢失的情况下,也能减少错误传播的范围,因为一个slice的损坏不会影响到其他slice的解码。
Slice可以是不同的类型,比如I-slice(只包含I宏块的slice)、P-slice(包含P宏块的slice)或B-slice(包含B宏块的slice),并且可以在编码时根据需要灵活配置。
Slice的边界不一定遵循图像内容的自然边界,而是根据编码策略和网络传输需求来确定。

Access Unit Delimiter (AUD) 的作用

分隔符功能:AUD作为NAL单元(Network Abstraction Layer Unit)的一种类型,其nal_unit_type值为9,它的主要目的是作为一个标识符,用来标记一个访问单元(Access Unit, AU)的开始。一个访问单元通常包含构成一个完整解码图像所需的所有NAL单元,比如一个I帧、P帧或者B帧及其相关的补充信息(如SPS、PPS等)。在复杂场景下,一个视频帧可能被编码为多个NAL单元(slice),AUD帮助解码器识别这些NAL单元属于同一个图像帧。

同步点:AUD为解码器提供了同步点,特别是在数据流可能存在错误或需要随机访问的情况下,解码器能够通过AUD快速定位到下一个完整图像的起始位置,这对于实现快速 seek、错误恢复以及同步播放控制等操作至关重要。

辅助解码:虽然AUD不是解码过程中的必需部分(即缺少AUD,解码器依然可以根据其他NAL单元类型解码视频),但它简化了解码器的设计,因为它允许解码器无须复杂的解析逻辑就能区分不同图像帧的边界,尤其是在处理包含多个slice的帧时。

兼容性和标准化:在FLV封装格式中加入AUD,有助于保持与H.264标准的兼容性,确保视频内容可以在遵循标准的解码器上正确播放,同时也便于视频流在不同系统间交换和回放。

FLV Header

FieldTypeComment
Signature1 byte必须为’F’(0x46)
Signature1 byte必须为’L’(0x4C)
Signature1 byte必须为’V’(0x56)
(版本)Version1 byte通常为0x01
TypeFlagsReserved5 bits必须为0
TypeFlagsAudio1 bit表示是否含有音频
TypeFlagsReserved1 bit必须为0
TypeFlagsVideo1 bit表示是否含有视频
DataOffset4 bytes文件头部的大小(从文件开始位置到body的偏移量),通常为9
FLV Body
FieldTypeComment
PreviousTagSize04 bytes总是0
Tag1FLVTAG结构第一个tag
PreviousTagSize04 bytes上一个tag的大小,包含了tag的头部。对FLV版本1来讲,它的值等于上一个tag的数据大小+11
Tag2FLVTAG结构第二个tag
PreviousTagSizeN - 14 bytes倒数第二个tag的大小
TagNFLVTAG结构最后一个tag
PreviousTagSizeN4 bytes最后一个tag的大小
FLV tag格式
FieldTypeComment
Tag类型(TagType)1 bytes8:音频、9:视频、18:script数据
数据大小(DataSize)3 bytes数据字段的长度
时间戳(Timestamp)3 bytes毫秒为单位,第一个tag时,该值总是0
时间戳扩展(TimeStampExtended)1 bytes时间戳扩展为4bytes,代表高8位,很少用到
流ID3bytes总是0
数据(Data)音频、视频或script数据实体

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

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

相关文章

西安交通大学 915 备考常见误区

看到助教在 915 全程班群里给同学们解答问题,我也是感触颇深,想起来我当年自身的一个备考情况。接下来结合我自身情况给同学们分析一下,为什么有的同学基础一般,最后分数却很高,有的同学基础很好,分数却一般…

Linux网络编程---多进/线程并发服务器

一、多进程并发服务器 实现一个服务器可以连接多个客户端,每当accept函数等待到客户端进行连接时 就创建一个子进程 思路分析: 核心思路:让accept循环阻塞等待客户端,每当有客户端连接时就fork子进程,让子进程去和客户…

html+css+js+jquery实现在网页端将手动输入用户的信息转化成表格

1.实现的效果图 2.css代码 ​<style>*{background-color: antiquewhite;}#ss{font-size:20px;text-align: center;}#inputForm { margin-bottom: 20px; } #userTable { width: 100%; border-collapse: collapse; } #userTable th, #userTable td { border: 1px …

Xcode for Mac:强大易用的集成开发环境

Xcode for Mac是一款专为苹果开发者打造的集成开发环境&#xff08;IDE&#xff09;&#xff0c;它集成了代码编辑器、编译器、调试器等一系列开发工具&#xff0c;让开发者能够在同一界面内完成应用的开发、测试和调试工作。 Xcode for Mac v15.2正式版下载 Xcode支持多种编程…

Linux进阶篇:CentOS7搭建NFS文件共享服务

CentOS7搭建NFS文件共享服务 一、NFS介绍 NFS(Network File System)意为网络文件系统&#xff0c;它最大的功能就是可以通过网络&#xff0c;让不同的机器不同的操作系统可以共享彼此的文件。简单的讲就是可以挂载远程主机的共享目录到本地&#xff0c;就像操作本地磁盘一样&…

Ubentu18.0+ORBSLAM2

Ubentu18.0ORB-SLAM2摄像头 引言&#xff1a; ​ 在视觉同步定位与地图构建&#xff08;Simultaneous Localization and Mapping, SLAM&#xff09;领域&#xff0c;ORB-SLAM2系统的出现标志着重要的技术进步。这个著名的SLAM系统由Juan D. Tards、Ral Mur-Artal等人开发&#…

RabbitMQ发布确认和消息回退(6)

概念 发布确认原理 生产者将信道设置成 confirm 模式&#xff0c;一旦信道进入 confirm 模式&#xff0c;所有在该信道上面发布的消息都将会被指派一个唯一的 ID(从 1 开始)&#xff0c;一旦消息被投递到所有匹配的队列之后&#xff0c;broker就会发送一个确认给生产者(包含消…

git 基础知识(全能版)

文章目录 一 、git 有三个分区二、git 基本操作1、克隆—git clone2、拉取—git fetch / git pull3、查看—git status / git diff3.1 多人开发代码暂存技巧 本地代码4、提交—git add / git commit / git push5、日志—git log / git reflog6、删除—git rm ‘name’7、撤销恢…

OceanBase开发者大会实录 - 阳振坤:云时代的数据库

本文来自2024 OceanBase开发者大会&#xff0c;OceanBase 首席科学家阳振坤的演讲实录——《云时代的数据库》。完整视频回看&#xff0c;请点击这里 >> 在去年的开发者大会中&#xff0c;我跟大家分享了我对数据库产品和技术一些看法&#xff0c;包括单机分布式一体化&…

字符函数·字符串函数·C语言内存函数—使用和模拟实现

字符函数字符串函数C语言内存函数 1.字符分类函数2. 字符转换函数3. strlen的使用和模拟实现4.strcpy的使用和模拟实现5.strcat的使用和模拟实现6.strcmp的使用和模拟实现7.strncpy的模拟和实现8.strncat的实现和模拟实现9.strncmp函数使用10.strstr的使用和模拟实现11.strtok函…

备考数通HCIE证书4点经验分享!

大家好&#xff0c;我是来自安阳工学院20级网络工程的刁同学&#xff0c;在2023年12月20日成功通过了华为Datacom HCIE认证&#xff0c;并且取得了笔试900多分&#xff0c;实验B的成绩。在此&#xff0c;我想把我的一些考证心得分享给正在备考的小伙伴们。 关于为什么考证 我…

Vue3+ts(day03:ref和reactive)

学习源码可以看我的个人前端学习笔记 (github.com):qdxzw/frontlearningNotes 觉得有帮助的同学&#xff0c;可以点心心支持一下哈&#xff08;笔记是根据b站上学习的尚硅谷的前端视频【张天禹老师】&#xff0c;记录一下学习笔记&#xff0c;用于自己复盘&#xff0c;有需要学…

tcp inflight 守恒算法的自动收敛

inflight 守恒算法看起来只描述理想情况&#xff0c;现实很难满足&#xff0c;是这样吗&#xff1f; 从 reno 到 bbr&#xff0c;无论哪个算法都在描述理想情况&#xff0c;以 reno 和 bbr 两个极端为例&#xff0c;它们分别描述两种理想管道&#xff0c;reno 将 buffer 从恰好…

Apollo 7周年大会:百度智能驾驶的展望与未来

本心、输入输出、结果 文章目录 Apollo 7周年大会&#xff1a;百度智能驾驶的展望与未来前言百度集团副总裁、智能驾驶事业群组总裁王云鹏发言 直播回放大会相关内容先了解 Apollo&#xfeff;开放平台 9.0架构图 发布产品Apollo 定义自己对于智能化的认知百度集团副总裁 王云鹏…

Grafana系列 | Grafana监控TDengine库数据 |Grafana自定义Dashboard

开始前可以去grafana官网看看dashboard文档 https://grafana.com/docs/grafana/latest/dashboards 本文主要是监控TDengine库数据 目录 一、TDengine介绍二、Grafana监控TDengine数据三、Grafana自定义Dashboard 监控TDengine库数据1、grafana 变量2、添加变量3、配置panel 一…

Docker——数据管理和网络通信

目录 一、Docker的数据管理 1.数据卷 2.数据卷容器 3.容器互联 二、Docker镜像的创建 1.基于现有镜像创建 2.基于本地模板创建 3.基于Dockerfile 创建 3.1联合文件系统&#xff08;UnionFS&#xff09; 3.2镜像加载原理 3.3为什么Docker里的Centos大小才200M 4.Dcok…

鸿蒙OpenHarmony【轻量系统 编写“Hello World”程序】 (基于Hi3861开发板)

编写“Hello World”程序 下方将通过修改源码的方式展示如何编写简单程序&#xff0c;输出“Hello world”。请在下载的源码目录中进行下述操作。 确定目录结构。 开发者编写业务时&#xff0c;务必先在./applications/sample/wifi-iot/app路径下新建一个目录&#xff08;或一…

CSS基础语法

CSS 标签选择器 内嵌式改变标签样式 <!DOCTYPE html> <html><head><meta charset"utf-8" /><title></title><!-- 属于标签选择器 --><style>p{font - size: 16px;color: red;}</style></head><bo…

Git学习路线

1.看书 把这本书看懂就可以了&#xff1b;这个是比较专业的一本书&#xff1b;比较系统&#xff1b;没有书的可以私信我 2.理解Git多个分区和多个分支 多个分区包括&#xff1a;工作区、暂存区、本地仓、本地的远端仓信息、远端仓 多个分区的状态 分支及其变化 3.记住常用命令…

国产麒麟系统下打包electron+vue项目(AppImage、deb)

需要用到的一些依赖包、安装包以及更详细的打包方法word以及麒麟官网给出的文档都已放网盘&#xff0c;链接在文章最后&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&a…
最新文章