精华内容
参与话题
问答
  • RTMP协议

    2020-07-27 21:35:29
    RTMP 基本概念 RTMP 创建流的基本流程 ...RTMP 协议中的握手 RTMP 真实的握手 建立RTMP连接 RTMP真的连接 创建RTMP协议RTMP流的创建 真实创建RTMP流 推RTMP流 播RTMPRTMP消息 RTMP消息格式 ...

    RTMP 基本概念

    在这里插入图片描述

    RTMP 创建流的基本流程

    • Socket 建立 TCP 连接
    • RTMP 握手
    • 建立 RTMP 连接
    • 创建 RTMP 流

    RTMP 协议中的握手

    在这里插入图片描述
    RTMP 真实的握手
    在这里插入图片描述

    建立RTMP连接

    在这里插入图片描述
    RTMP真的连接
    在这里插入图片描述

    创建RTMP流

    协议中RTMP流的创建
    在这里插入图片描述
    真实创建RTMP流
    在这里插入图片描述

    推RTMP流

    在这里插入图片描述

    播RTMP流

    在这里插入图片描述

    RTMP消息

    RTMP消息格式

    在这里插入图片描述

    RTMP消息类型

    在这里插入图片描述

    展开全文
  • RTMP 协议

    2020-12-04 10:21:45
    RTMP协议是Real Time Message Protocol(实时信息传输协议)的缩写,它是由Adobe公司提出的一种应用层的协议,用来解决多媒体数据传输流的多路复用(Multiplexing)和分包(packetizing)的问题。 RTMP协议从属于应用...

    一、概述
    RTMP协议是Real Time Message Protocol(实时信息传输协议)的缩写,它是由Adobe公司提出的一种应用层的协议,用来解决多媒体数据传输流的多路复用(Multiplexing)和分包(packetizing)的问题。

    RTMP协议从属于应用层,被设计用来在适合的传输协议(如TCP)上复用和打包多媒体传输流(如音频、视频和互动内容)。RTMP提供了一套全双工的可靠的多路复用消息服务,类似于TCP协议[RFC0793],用来在一对结点之间并行传输带时间戳的音频流,视频流,数据流。通常情况下,不同类型的消息会被分配不同的优先级,当网络传输能力受限时,优先级用来控制消息在网络底层的排队顺序。

    握手、消息块概念
    握手的目的是为了确认对端RTMP的Version和确认对端能互相通信。
    消息块就是消息的载体,是RTMP协议最重要的载体,这个载体是有一定格式的,如果把Client和Server端当作铁路的两个站点,
    那这个消息块就是火车,它负责运输货物。正如火车有火车头、车厢一样,消息块也有基本头,消息头和消息负载。RTMP协议当中,
    除了握手协议,其他的数据都是以消息块的方式发送的,发送一个消息时,当块大小比需要发送的消息的字节数更大时,
    一个消息块就相当于一个消息,否则消息需要分成多个消息块。


    握手
    要建立一个有效的RTMP Connection链接,首先要“握手”:客户端要向服务器发送C0,C1,C2(按序)三个chunk,服务器向客户端发送S0,S1,S2(按序)三个chunk,然后才能进行有效的信息传输。RTMP协议本身并没有规定这6个Message的具体传输顺序,但RTMP协议的实现者需要保证这几点如下:

    客户端要等收到S1之后才能发送C2

    客户端要等收到S2之后才能发送其他信息(控制信息和真实音视频等数据)

    服务端要等到收到C0之后发送S1

    服务端必须等到收到C1之后才能发送S2

    服务端必须等到收到C2之后才能发送其他信息(控制信息和真实音视频等数据)

    握手流程
    握手是一切的开始,Client和Server两个站点之前要运输货物,首先得先互相通知对方,确认铁轨是否符合火车运行,是否畅通无阻,是否能准确的运输货物到对端。
    实际的流程大概是这样的:

    Client发送带有1byte的C0和固定长度为1536byte的C1。
    Server发送S0S1S2给Client。
    Client发送C2。

     

    RTMP块流

    实时消息传递协议块流(RTMP块流)。RTMP块流作为一款高级多媒体流协议提供了流的多路复用和打包服务。RTMP块流被设计用来传输实时消息协议,它可以使用任何协议来发送消息流。每个消息都包含时间戳和有效类型标识。RTMP块流和RTMP适用于各种视听传播的应用程序,包括一对一的,和一对多的视频直播、点播服务、互动会议应用程序。

    当使用一个可靠的传输协议如TCP[RFC0793]时,RTMP块流提供了一种可以在多个流中,基于时间戳的端到端交付所有消息的方法。RTMP块流不提供任何优先级或类似形式的控制,但可以使用更高级别的协议来提供这样的优先级。

    RTMP块流不仅包含了自己的协议控制信息,同时也提供了一个更高级别的协议机制,用来嵌入用户控制信息。

     

    RMTP消息格式

    RMTP消息被分割成多个块,用来在更高的协议中支持多路复用。在消息格式时,应该包含以下字段:

    时间戳

    消息的时间戳。这个字段占用4字节。

    长度

    消息的有效长度。如果消息头不能被忽略,它应该包括长度。这个字段在块头中占用3字节。

    类型ID

    各种类型的协议控制消息的ID。这些消息使用RTMP块流协议和更高级别的协议来传输信息。所有其他类型的ID可以用在高级协议,这对于RTMP块流来说,是不透明的。事实上,RTMP块流中没有要求使用这些值作为类型;所有(无协议的)消息可能是相同的类型,或者应用程序使用这个字段来区分多个连接,而不是类型。这个字段在块头中占用1字节。

    消息流ID

    消息流ID可以是任意值。当同一个块流被复用到不同的消息流中时,可以通过消息流ID来区分它们。另外,对于RTMP块流而言,这是一个不透明值。该字段占用4字节,使用小端序。

    RTMP协议中基本的数据单元称为消息(Message)。当RTMP协议在互联网中传输数据的时候,消息会被拆分成更小的单元,称为消息块(Chunk)。

    消息

    消息是RTMP协议中基本的数据单元。不同种类的消息包含不同的Message Type ID,代表不同的功能。RTMP协议中一共规定了十多种消息类型,分别发挥着不同的作用。例如,Message Type ID在1-7的消息用于协议控制,这些消息一般是RTMP协议自身管理要使用的消息,用户一般情况下无需操作其中的数据。Message Type ID为8,9的消息分别用于传输音频和视频数据。Message Type ID为15-20的消息用于发送AMF编码的命令,负责用户与服务器之间的交互,比如播放,暂停等等。消息首部(Message Header)有四部分组成:标志消息类型的Message Type ID,标志消息长度的Payload Length,标识时间戳的Timestamp,标识消息所属媒体流的Stream ID。消息的报文结构如下图所示。

     

    消息块

    在网络上传输数据时,消息需要被拆分成较小的数据块,才适合在相应的网络环境上传输。RTMP协议中规定,消息在网络上传输时被拆分成消息块(Chunk)。消息块首部(Chunk Header)有三部分组成:用于标识本块的Chunk Basic Header,用于标识本块负载所属消息的Chunk Message Header,以及当时间戳溢出时才出现的Extended Timestamp。消息块的报文结构如下图所示。

     

    消息分块

    在消息被分割成几个消息块的过程中,消息负载部分(Message Body)被分割成大小固定的数据块(默认是128字节,最后一个数据块可以小于该固定长度),并在其首部加上消息块首部(Chunk Header),就组成了相应的消息块。消息分块过程如下图所示,一个大小为307字节的消息被分割成128字节的消息块(除了最后一个)。

    RTMP传输媒体数据的过程中,发送端首先把媒体数据封装成消息,然后把消息分割成消息块,最后将分割后的消息块通过TCP协议发送出去。接收端在通过TCP协议收到数据后,首先把消息块重新组合成消息,然后通过对消息进行解封装处理就可以恢复出媒体数据。

     

    而在RTMP协议中,最重要的就是流的建立,涉及到的握手协议。

    展开全文
  • rtmp协议

    千次阅读 2015-07-23 15:18:50
    rtmp协议是adobe公司发明的直播流协议,是目前主流的视频上传协议。 2.术语 AMF(Action Message Format)是在flash和flex中与远程服务端交换数据的一种格式。它是二进制格式,Flash应用与服务端或数据库...
    1.概述
    rtmp协议是adobe公司发明的直播流协议,是目前主流的视频上传协议。
    2.术语
    • AMF(Action Message Format)是在flash和flex中与远程服务端交换数据的一种格式。它是二进制格式,Flash应用与服务端或数据库通过RPC交换数据时,通常都采用这种格式。AMF 1 诞生于Flash Player6,发展到现在已经变成了了AMF3。
    • RTMP(Real-Time Messaging Protocol实时消息传送协议)的缩写,它是Adobe Systems公司为Flash播放器和服务器之间音频、视频和数据传输开发的协议。这是一个标准的,未加密的实时消息传递协议,默认端口是1935,如果未指定连接端口,那么flash客户端会尝试连接其他端口,其尝试连接顺序按照下列顺序依次连接:1935、443、80(RTMP), 80(RTMPT)。
    • RTMPT,RTMP的变种,此协建立在HTTP协议之上,是通过HTTP封装后的RTMP协议,默认端口80。
    • RTMPS,RTMP的另一个变种,此协议是通过SSL(Secure Sockets Layer 安全套接层)加密的RTMP协议,为数据通讯提供安全支持。SSL在传输层对网络连接进行加密,默认端口443。
    • RTMPE,RTMP的变种,RTMPE是一个加密版本的RTMP,和RTMPS不同的是RTMPE不采用SSL加密,RTMPE加密快于SSL,并且不需要认证管理。如果没有指定RTMPE端口,Flash播放器将像RTMP协议一样依次扫描下列端口,1935(RTMPE),443(RTMPE) ,80(RTMPE),80(RTMPTE)。
    • RTMPTE,RTMPTE 这个协议是一个通过加密通道连接的RTMPE,默认端口80。
    • RTMFP,RTMFP是Adobe公司开发的一套新的通信协议,该协议可以让使用Adobe Flash Player的终端用户之间进行直接通信。
    3.握手
         C0 和S0:分别是1 个byte 的数据块,它主要是为了指明RTMP 的版本。对于Client 来说代表了客户端请求使用的版本,而对Server 来说,表明了服务端选择使用的版本。现在所使用的版本号都是0x03。如果Client 请求了一个非法的版本号,那么Server 应该返回版本号0x03。Client 要么同意Server 的选择,要么放弃握手。
         C1 和S1 分别是一个1536 bytes 长的数据块。这个数据块的前4 个bytes 指明了这个数据块创建的当前时间戳,也可以是0。后面4 个bytes 通常是0,也可以是版本号,对于Client来说是FP 的版本号,对于Server 来说是FMS 的版本号。随后的1528 个bytes 的值是任意填写的。
         C2 和S2 也分别是一个1536 bytes 长的数据块。所不同的是,对于C2 来说,time 和time2的值必须是从S1 中读取的;反过来对S2 也一样,是从C1 中读取的。另一方面剩下的1528个bytes 也不再是随机值了,对于C2 来说这些bytes 必须来自S1,反过来对S2 也一样,这些bytes 必须来自C1。总结下来就是说,C2 要把之前S1 的1536 bytes 内容完完整整的发回给Server,S2 也做类似的动作,把之前收到的C1 的内容完整的发回给Client。
    • 首先由Client 发送C0、C1 给Server,并且等待S1 的到来。
    • 当Server 收到C0 之后,发送S0 和S1 给Client,在收到C1 之后,发送S2 给Client,并等待C2 的到来。
    • 当Client 收到S1 之后,发送C2 给Server,在收到S2 之后,就可以发送后续的数据了。
    • 当Server 收到C2 之后,就可以发送后续的数据了。
    握手中的优化:
         由于C0、S0 只有1 个bytes,出于优化考虑,通常C0 和C1 是一起发送的,也就是握手开始发送1537 个bytes。由于Server 收到C1 就可以发送S2 了,所以通常Server 会一次性返回S0、S1 和S2 给Client。由于Client 发送完C2 之后就可以发送后续数据包了,因此通通常C2 之后有可能会跟随其他的数据块。

    4.Trunk stream

    4.1 message stream
         message stream是逻辑意义上的流,包含command stream和media stream两种。command stream表示命令数据流,media stream表示媒体流。Command stream是指专门用来在Client 和Server 间传递命令控制消息的数据流。media stream是指包括音频、视频和元数据(metadata)在内的媒体流。每条message stream会由Flash Media Server 分配一个Message Stream ID,这个ID 在整个视频通讯过程中保持不变。Command channel 的Message Stream ID 为0。
    4.2 chunk stream
         Chunk Stream 是整个视频通讯会话过程中的一段数据。这段数据可以是任意类型的消息,包括音频、视频、控制消息等。一条Chunk Stream 包含了若干个Chunk。每条Chunk Stream 都会分配一个Chunk Stream ID,并标明Msg Stream ID。Chunk Stream ID 是可以在协议允许变化的范围内任意指定的(除了包含命令控制消息的Chunk),它的主要用途是让Chunk 与Chunk 之间产生关联,从而降低Chunk Header 的额外开销。
    4.3 chunk
         Chunk:由于Chunk Stream包含的数据往往比较长,出于各种考虑经常会把较长的ChunkStream 分成若干小段,那么每一小段就叫做一个Chunk。所有的Chunk 所包含消息必须和Chunk Stream 中的其他消息类型一致。每个Chunk 都会分配一个Chunk Stream ID。由于在实际的数据传输中,Message Stream 只是逻辑上的概念,因此每个Chunk 也都会包含一个Msg Stream ID。Chunk 的大小是人为指定的,客户端可以与服务器采用不同的chunk 大小。在没有指定之前,chunk 大小采用默认值128 字节。

         由上图我们可以总结出这几种消息之间的关系:在一条TCP 连接中,包含着几条Message Stream,绝大部分情况下是Control Msg Stream 和Media Msg Stream。而这些Msg Stream 由一段一段的Chunk Stream 组成,每个Chunk Stream 都带有一个Message Stream ID 以标识这个Chunk Stream 是属于哪一个Msg Stream。由于Chunk Stream 所包含的数据比较大,常常又被切分成更小的Chunk,每个Chunk 都带有一个Chunk Stream ID 以标识它属于哪一个Chunk Stream。
    4.4 chunk格式
         每个Chunk 都由Chunk Header + Chunk Data 组成。而Chunk Header 在逻辑上又可分为3部分。
    Basic Header
         Basic Header 包含fmt 和cd id 两个字段,fmt 表示协议头格式(Chunk Message HeaderFormat),cd id 表示流id(Chunk Stream ID)。Basic Header 长度为1-3 个字节,由cs id 字段来决定。
    • Fmt,决定了Chunk Message Header 的格式,取值为0-3,共四种格式。
    • Cs id,取值范围是0 – 65599,0-2 为保留值。0 表示basic header 长度为2 个字节,1 表示长度为3 个字节,2 表示该chunk 为控制消息(同时Message Stream ID必须是0)。当Basic Header 长度为1 时,cs id 取值2-63。当Basic Header 长度为2时,cs id = 64 + the second byte。当Basic Header 长度为3 时,cs id = 64 + the second byte + the third byte × 256。
    Chunk Msg Header
         Fmt 取值从0-3,决定了四种长度的chunk msg header,可取值为11B、7B、4B、0B。
    • type0(fmt=0)
    • type1(fmt=1)
    Type1的trunk 和上一个trunk 拥有相同的message stream id。且Timestamp delta 表示相对上一个trunk 的时间差,实战中大多数音视频数据都采用相对时间戳。
    • type2(fmt=2)
    Type 2 的trunk 和上一个trunk 拥有相同的长度、消息类型、消息流id。
    • type3(fmt=3)
    Type 3 的trunk msg header 长度为0,表示和上一个trunk 所有参数都相同。如果type3
    跟在type0 后面,则type3 的相对时间戳也是0。

    注:通常情况下一个type3不会独立存在,而是跟在type0或type1后面。一个数据包(多帧)通常比一个chunk包大,所以要由多个chunk存放一个数据包,这时第一个chunk通常是type0或type1,后面跟着的chunk是type3。由于chunk中的message length指的是数据长度,所以解析完第一个chunk,数据还没有完毕,还需要继续解析后面type3的chunk,这时type3的头信息直接使用前面的type0或type1即可。有一点需要注意,后面type3的chunk长度实际上是剩余长度,而不是和前面的chunk长度相同。

    Extended Timestamp
         这个字段是可选的,长度为4 个字节。只有当正常时间戳超过0xffffff 时,这个字段才存在。Type3 类型的trunk 一定不能有这个字段。

    Chunk Data
         Chunk Data 可以是音视频数据、元数据、控制消息。

    5.控制消息
         控制消息是作为rtmp trunk stream 的负载存在的。当Message type id 取值为0-7 时,表示控制消息。同时Chunk Basic Header 的Chunk Stream ID 必须为2,Chunk Msg Header 的Message Stream ID 必须为0。其中消息7一般不用。
    • 0x01 – Set Chunk Size
    这个消息是双向发送的,一方告诉另一方自己的trunk 大小。一旦设置成功则后续所有trunk 大小会一直保持这个值。
    • 0x02 – About Message
    用来通知正在等待接收指定的Chunk Stream 的对端,放弃等待,并且放弃处理AboutMessage 中所指明的chunk stream id 的Chunk Stream 中的消息。注意这条命令只是撤销一个Chunk Stream 的数据,并不是整条Message Stream。实战中这个消息基本不会发送, 在rtmpdump 中也不会处理这个消息。
    • 0x03 – Acknowledgement
    用来告知server,到目前为止已经收到了一定量的数据。0x05 消息指定了server 发送的窗口最大值,如果在发送的数据达到了最大值还没有收到客户端发来的报告,则server 会停止发送数据,经过实测fms 超过三倍这个窗口时会停止发送数据。因此客户端必须在收到数据未达到最大值前报告自己接收到的字节数。Sequence num 表示到目前为止客户端收到的字节数,但是要注意这个值会溢出,溢出后server不久便会停止发送数据,rtmpdump 就有这个问题。
    • 0x04 – User Control Message
    这条消息是用户控制消息。主要是用来在Client 与Server 之间发送消息通知对方用户控制事件。这个消息的前2 个bytes 是指事件的类型,后面是事件的数据。根据Event Type 的不同,Event Data 的长度是不同的。
    • Type0,Stream Begin,服务器端通知客户端message stream 已经可以正常工作了。Event Data 是0,长度为4 个字节。这个事件是当服务器收到客户端的connect 命令后发送给客户端的。
    • Type1,Stream EOF,服务器端通知客户端播放已经结束了。Event Data 表示流ID,长度为4 个字节。
    • Type2,Stream Dry,服务器端通知客户端message stream 已经没有数据了。EventData 表示流ID,长度为4 个字节。服务器端在一段时间内没有检测到消息则可以给客户端发送这个事件。
    • Type3,SetBuffer Length,客户端通知服务器端用来接收数据的buffer 大小(以毫秒为单位)。Event Data 共8 比特,前4 比特表示流ID,后4 比特代表buffer 大小。客户端在服务器端处理流之前发送这个事件。
    • Type4,StreamIsRecorded,服务器端通知客户端这个流需要被录像。Event Data 表示流ID,长度为4 个字节。
    • Type6,PingRequest,服务器端用于测试客户端是否存活。Event Data 为服务器时间戳,长度为4 个字节。
    • Type7,PingResponse,客户端反馈服务器端PingRequest 消息,Event Data 为ping消息中的时间戳,长度为4 个字节。Ping 消息必须回,否则一段时间后server 会停止服务。
    • 0x05 – Window Acknowledgement Size
    这条消息也叫“Server Bandwidth”,主要是用于告知对方自己希望对方接收多少个字节之后回应一个Ack 确认消息。这个具体的字节数也叫做窗口大小。通常Server 会在成功处理Client 发出的connect 请求后发送这个Msg 更新Client 的Ack 窗口大小
    • 0x06 – Set Peer Bandwidth
    这条消息也叫“Client Bandwidth”,和Msg Type 0x05 相对应,这条消息是告诉对方要以怎样的带宽发送数据,带宽值应该与对方的Windows Size 相同。如果收到这条消息的一方发现自己的Windows Size 和这条消息中指定的Bandwidth 不同,应该回应一个Msg Type0x05。另外这条消息还有一个额外的字段Limit type,它的取值分别为:hard(0)、soft(1)、dynamic(2)。
    Hard:对方的发送数据带宽必须严格符合指定带宽。
    Soft,对方发送数据带宽可以自行决定。必要时接收方可以限制对方带宽。
    Dynamic,带宽既可以是hard 也可以是soft。

    6.命令消息
         当Message type id 取值为14 时,表示命令消息。命令消息对Chunk Stream ID 和MessageStream ID 没有特殊要求,而控制消息是有的。命令消息分为两大类,NetConnection 和NetStream。
         NetConnection 包括:connect、call、close、createStream 命令。
         NetStream 包括:play、play2、deleteStream、closeStream、receiveAudio、receiveVideo、publish、seek、pause 命令。
         命令的格式为command name + transaction ID + 其他,所有字段都是用AMF 格式封装的,transaction ID的含义不明确,虽然官方文档有规定,但是实战中不是这么用的。下面我们只介绍最常用的connect、createStream、Play 命令,这三个命令是必须的,其他命令可以不用。
    • Connect
              Connect 命令是client 发送给server 的第一个命令,而此时chunk 大小还没有设定。因此client 采用默认值128 字节。
    • createStream
              Createstream 用于与服务器创建一条逻辑链路,传输音频、视频、元数据。
    • Play
              开始播放一条stream,streamid为createstream返回的id。
    7.客户端与服务器交互流程
         客户端与服务器之间的交互可以划分为三个过程:握手、设置参数、播放。
    • 握手

    • 设置参数

    • 播放

    • 从rtmpdump观察到的交互流程
    client                                                                                     server
         1.RTMP_Connect----------------------------------------------------------------------->
         2.HandleServerBW<---------------------------------------------------------------------
         3.HandleClientBW<----------------------------------------------------------------------
         4.HandleChangeChunkSize<------------------------------------------------------------
         5.HandleInvoke(_result for connect, NetConnection.Connect.Success)<-----------
         6.SendServerBW----------------------------------------------------------------------->
         7.SendRecvBuffSize-------------------------------------------------------------------->

         8.SendCreateStream------------------------------------------------------------------>
         9.HandleInvoke(onBWDone)<----------------------------------------------------------
         10.SendCheckBW(_checkbw)--------------------------------------------------------->
         11. HandleInvoke(_result for createStream, 得到stream id)<-----------------------
         12.SendPlay----------------------------------------------------------------------------->
         13.SendClientBufferTime-------------------------------------------------------------->
         14.HandleInvoke(_onbwcheck)<-------------------------------------------------------
         15.SendCheckBwResult---------------------------------------------------------------->
         16.ChangeChunkSize<------------------------------------------------------------------
         17.HandleCtrl(stream is recorded)<---------------------------------------------------
         18.HandleInvoke(onStatus: NetStream.Play.Reset)<--------------------------------
         19.HandleCtrl(Stream Begin)<---------------------------------------------------------
         20.HandleInvoke(onStatus: NetStream.Play.Start)<---------------------------------
         21.MetaData(RtmpSampleAccess)<---------------------------------------------------
         22.MetaData(NetStream.Data.Start)<-------------------------------------------------
         23.MetaData(onMetaData)<------------------------------------------------------------

    说明:HandleInvoke指的就是命令消息,HandleCtrl指的是控制消息。

    1到7为设置参数阶段

    8到23为播放阶段
         第13步SendClientBufferTime,这个命令是向服务器发送本地接收缓冲区的大小,以时间(毫秒)为单位。实战中发现,FMS流控就是依靠这个参数来做的。如果将这个值设置为5000,则我们会发现FMS快速发送一部分数据(应该是5秒的数据),然后等待大约5秒,然后再发送一部分数据,这种流控其实很不合理。

    8.混合消息
         混合消息(Aggregate Message)是由多个消息组合而成的消息,Msg type 为0x16。之所以会存在这样的打包消息。是为了减少FMS 因为IO 过于频繁而导致CPU 开销过大的一种优化。

     混合消息中包含很多子消息,实战中发现子消息只有视频、音频、元信息三种。需要说明一点的是,子消息中的head 指的是flv 头而不是rtmp 头。如果非要解析这个数据包的话必须结合flv 头格式进行解析。还有注意一点,flv头中的时间戳都是绝对时间戳,和rtmp 流的时间戳不是一个体系的。如果要计算子消息的时间戳则要结合混合消息头消息中的时间戳。子消息的相对时间可以这样来计算:第一个子消息的时间戳与混合消息的时间戳相同,后续子消息用自己的绝对时间戳减去第一个子消息的绝对时间戳,然后再加上混合消息的时间戳即可。在Aggregate Message body 的打包消息列表中,Back Pointer 的内容是前一个Msg 的尺寸,包括Msg Header,这和FLV File Format 中的PreviousTagSize 非常相似。

    9.加流控信息
         flv文件头非常小,通常只有几百个字节,好处是元信息很少便于传输,坏处是不便于对数据做索引。下面两个工具可以给flv增加关键帧索引信息,即关键帧的位置和播放时间。
         元数据主要有两个数组,times和filepositions,这两个数组是相对应的,比如times[10]=184.4,而filepositions[10]=10000,意思是视频在184.4秒处的文件位置是10000,当向http服务器(例如Nginx)视频信息时http://localhost/flv/1.flv?start=10000,则视频就会从184.4秒处开始播放,这样就实现了seek到184.4的效果。但是需要注意的是,start的数值必须是关键帧数组里的filepositions的值,否则不会成功。

    flvtool2,下载地址:http://rubyforge.org/frs/?group_id=1096
    yamdi,官方:http://yamdi.sourceforge.net(用代理才能访问到)

    1.命令(cmd进入到yamdi.exe所在文件夹),执行 yamdi -i sample.flv -o sample_with_metadata.flv  
     sample.flv是原视频文件,而sample_with_metadata.flv  是补全完元数据的视频(主要是包含了关键帧信息)
    展开全文

空空如也

1 2 3 4 5 ... 20
收藏数 4,531
精华内容 1,812
关键字:

rtmp协议