封装 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.rhkb.cn/news/314168.html

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

相关文章

indexDB 大图缓存

背景 最近在项目中遇到了一个问题:由于大屏背景图加载速度过慢,导致页面黑屏时间过长,影响了用户的体验。从下图可以看出加载耗时将近一分钟 IndexDB 主要的想法就是利用indexDB去做缓存,优化加载速度;在这之前&am…

C语言——内存函数的实现与模拟

1. memcpy 函数 与strcpy 函数类似 1.头文件 <string.h> 2.基本格式 • 函数memcpy从source的位置开始向后复制num个 字节 的数据到destination指向的内存位置。 • 这个函数在遇到 \0 的时候并不会停下来。 • 如果source和destination有任何的重叠&#xff0…

C# WinForm —— 10 单选按钮与复选框的介绍与使用

单选按钮 RadioButton 一组单选按钮中&#xff0c;只能选择一个&#xff0c;互相排斥 常用属性、事件&#xff1a; 属性用途(Name)单选按钮的ID&#xff0c;在代码里引用的时候会用到,一般以 rb开头Text单选按钮旁边显示的 文本信息Checked单选按钮的勾选状态Appearance控制单…

SpringCloud系列(18)--将服务提供者Provider注册进Consul

前言&#xff1a;在上一章节中我们把服务消费者Consumer注册进了Zookeeper&#xff0c;并且成功通过服务消费者Consumer调用了服务提供者Provider&#xff0c;而本章节则是关于如何将服务提供者Provider注册进Consul里 准备环境&#xff1a; 先安装Consul&#xff0c;如果没有…

【OceanBase诊断调优】—— 4013 内存爆问题的排查

本文介绍 4013 内存爆问题的排查。 内存爆的类型 内存爆主要分为五类&#xff0c;可以通过关键词 OOPS 确定内存爆的类型。 内存爆的类型日志信息&#xff08;关键字为 [OOPS]&#xff09;SINGLE_ALLOC_SIZE_OVERFLOWsingle alloc size large than 4G is not allowed(alloc_…

vue项目使用百度地图

打开百度地图开放平台 百度地图开放平台 | 百度地图API SDK | 地图开发 在控制台新建应用 复制访问应用的ak 可修改地图样式 使用部分 <!-- 引入地图 --><div class"main-aside"><div id"b-map-container"></div></div> …

案例-部门管理-删除

黑马程序员JavaWeb开发教程 文章目录 一、查看页面原型二、查看接口文档三、开发1、Controller2、Service&#xff08;1&#xff09;service接口层&#xff08;3&#xff09;service实现层 3、Mapper4、Postman 一、查看页面原型 二、查看接口文档 三、开发 1、Controller 因…

SpringWebFlux RequestBody多出双引号问题——ProxyPin抓包揪出真凶

缘起 公司有个服务做埋点收集的&#xff0c;可以参考我之前的文章埋点日志最终解决方案&#xff0c;今天突然发现有些数据日志可以输出&#xff0c;但是没法入库。 多出的双引号 查看Flink日志发现了JSON解析失败&#xff0c;Flink是从Kafka拿数据&#xff0c;Kafka本身不处…

Magnet for Mac:高效窗口管理工具

Magnet for Mac是一款专为Mac用户设计的窗口管理工具&#xff0c;旨在帮助用户更高效地管理和布局多个应用程序窗口&#xff0c;提升工作效率。 Magnet for Mac v2.14.0中文免激活版下载 这款软件拥有直观易用的界面和丰富的功能&#xff0c;支持用户将屏幕分割成多个区域&…

【漏洞分析】浅析android手游lua脚本的加密与解密(一)

主要用到的工具和环境&#xff1a; 1 win7系统一枚 2 quick-cocos2d-x的开发环境&#xff08;弄一个开发环境方便学习&#xff0c;而且大部分lua手游都是用的cocos2d-x框架&#xff0c;还有一个好处&#xff0c;可以查看源码关键函数中的特征字符串&#xff0c;然后在IDA定位到…

Electron中使用Prisma(以SQLite为例)

1、安装 Prisma 打开终端&#xff0c;执行以下命令安装 Prisma CLI&#xff1a; npm install prisma -g 2、初始化 Prisma 项目 在工作目录中执行以下命令来初始化一个新的 Prisma 项目&#xff1a; prisma init 这将创建一个新的文件夹&#xff0c;包含了必要的文件和目…

vue echarts折线图 折线堆积图和折线面积图

vue echarts折线图 折线堆积图和折线面积图 1、折线堆积图和折线面积图的结合&#xff1b; 上代码 <template><section><divid"performaceLineChart"ref"performaceLineChartRef"style"width: 100%; height: 500px"></d…

文旅IP孵化打造抖音宣传推广运营策划方案

【干货资料持续更新&#xff0c;以防走丢】 文旅IP孵化打造抖音宣传推广运营策划方案 部分资料预览 资料部分是网络整理&#xff0c;仅供学习参考。 PPT可编辑&#xff08;完整资料包含以下内容&#xff09; 目录 文旅IP抖音运营方案 1. 项目背景与目标 - 背景&#xff1a…

ShardingSphere 5.x 系列【25】 数据分片原理之 SQL 解析

有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot 版本 3.1.0 本系列ShardingSphere 版本 5.4.0 源码地址:https://gitee.com/pearl-organization/study-sharding-sphere-demo 文章目录 1. 分片执行流程1.1 Simple Push Down1.2 SQL Federation2. SQL 解析2.1 解析…

【stomp 实战】Spring websocket使用详解和基本原理

spring框架对websocket有很好的支持&#xff0c;stomp协议作为websocket的子协议&#xff0c;Spring也做了很多封装&#xff0c;让我们在开发中易于使用。 学习使用Spring的Websocket模块&#xff0c;当然最好的办法就是看官网说明了。本篇文章对官网做一些简述和个人的理解。 …

Java设计模式 _结构型模式_适配器模式

一、适配器模式 **1、适配器模式&#xff08;Adapter Pattern&#xff09;**是一种结构型设计模式。适配器类用来作为两个不兼容的接口之间的桥梁&#xff0c;使得原本不兼容而不能一起工作的那些类可以一起工作。譬如&#xff1a;读卡器就是内存卡和笔记本之间的适配器。您将…

国产麒麟v10系统下打包electron+vue程序,报错unknown output format set

报错如下&#xff1a; 报错第一时间想到可能是代码配置原因报错&#xff0c;查看代码似乎感觉没啥问题 又查看具体报错原因可能是因为icon的原因报错&#xff0c;后面查阅发现ico在各系统平台会不兼容&#xff0c;也就是ico是给win下使用的&#xff0c;此处改下图标格式就ok&am…

JavaScript-3(内置对象+数组对象+字符串对象)

目录 1.预解析 2.对象 什么是对象 创建对象的三种方法 利用字面量创建方法 利用new Object创建对象 构造函数创建对象 new关键字 遍历对象 3.内置对象 Math对象 Math概述 Math随机数 Date日期对象 格式化日期 Date总的时间毫秒 4.数组对象 创建数组的两种方式…

vue elementui el-table 表格里边展示四分位图

vue elementui el-table 表格里边展示四分位图 直接上代码&#xff08;效果图在文章末尾&#xff09;&#xff1a; 父组件&#xff1a; <template> <el-table size"small":header-cell-style"headerCellStyle()"style"width: 100%;"…

clickhouse与oracle传输数据

参考 https://github.com/ClickHouse/clickhouse-jdbc-bridge https://github.com/ClickHouse/clickhouse-jdbc-bridge/blob/master/docker/README.md clickhouse官方提供了一种方式&#xff0c;可以实现clickhouse与oracle之间传输数据&#xff0c;不仅仅是oracle&#xff0…