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

2024-04-27 07:52

本文主要是介绍封装 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数据实体

这篇关于封装 H.264 视频为 FLV 格式然后推流的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


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

相关文章

鸿蒙中Axios数据请求的封装和配置方法

《鸿蒙中Axios数据请求的封装和配置方法》:本文主要介绍鸿蒙中Axios数据请求的封装和配置方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1.配置权限 应用级权限和系统级权限2.配置网络请求的代码3.下载在Entry中 下载AxIOS4.封装Htt

基于Python和MoviePy实现照片管理和视频合成工具

《基于Python和MoviePy实现照片管理和视频合成工具》在这篇博客中,我们将详细剖析一个基于Python的图形界面应用程序,该程序使用wxPython构建用户界面,并结合MoviePy、Pill... 目录引言项目概述代码结构分析1. 导入和依赖2. 主类:PhotoManager初始化方法:__in

Python将博客内容html导出为Markdown格式

《Python将博客内容html导出为Markdown格式》Python将博客内容html导出为Markdown格式,通过博客url地址抓取文章,分析并提取出文章标题和内容,将内容构建成html,再转... 目录一、为什么要搞?二、准备如何搞?三、说搞咱就搞!抓取文章提取内容构建html转存markdown

用js控制视频播放进度基本示例代码

《用js控制视频播放进度基本示例代码》写前端的时候,很多的时候是需要支持要网页视频播放的功能,下面这篇文章主要给大家介绍了关于用js控制视频播放进度的相关资料,文中通过代码介绍的非常详细,需要的朋友可... 目录前言html部分:JavaScript部分:注意:总结前言在javascript中控制视频播放

Python基于wxPython和FFmpeg开发一个视频标签工具

《Python基于wxPython和FFmpeg开发一个视频标签工具》在当今数字媒体时代,视频内容的管理和标记变得越来越重要,无论是研究人员需要对实验视频进行时间点标记,还是个人用户希望对家庭视频进行... 目录引言1. 应用概述2. 技术栈分析2.1 核心库和模块2.2 wxpython作为GUI选择的优

SpringBoot中封装Cors自动配置方式

《SpringBoot中封装Cors自动配置方式》:本文主要介绍SpringBoot中封装Cors自动配置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录SpringBoot封装Cors自动配置背景实现步骤1. 创建 GlobalCorsProperties

如何自定义Nginx JSON日志格式配置

《如何自定义NginxJSON日志格式配置》Nginx作为最流行的Web服务器之一,其灵活的日志配置能力允许我们根据需求定制日志格式,本文将详细介绍如何配置Nginx以JSON格式记录访问日志,这种... 目录前言为什么选择jsON格式日志?配置步骤详解1. 安装Nginx服务2. 自定义JSON日志格式各

python dict转换成json格式的实现

《pythondict转换成json格式的实现》本文主要介绍了pythondict转换成json格式的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下... 一开始你变成字典格式data = [ { 'a' : 1, 'b' : 2, 'c编程' : 3,

Java导入、导出excel用法步骤保姆级教程(附封装好的工具类)

《Java导入、导出excel用法步骤保姆级教程(附封装好的工具类)》:本文主要介绍Java导入、导出excel的相关资料,讲解了使用Java和ApachePOI库将数据导出为Excel文件,包括... 目录前言一、引入Apache POI依赖二、用法&步骤2.1 创建Excel的元素2.3 样式和字体2.

JAVA封装多线程实现的方式及原理

《JAVA封装多线程实现的方式及原理》:本文主要介绍Java中封装多线程的原理和常见方式,通过封装可以简化多线程的使用,提高安全性,并增强代码的可维护性和可扩展性,需要的朋友可以参考下... 目录前言一、封装的目标二、常见的封装方式及原理总结前言在 Java 中,封装多线程的原理主要围绕着将多线程相关的操