publish
对于推流端,经过releaseStream,createStream消息之后,得到了_result消息之后,接下来客户端就可以发起publish消息。推流端使用publish消息向rtmp服务器端发布一个命名的流,发布之后,任意客户端都可以以该名称请求视频、音频和数据。我们首先来看一下publish消息的组织结构:
- commandName:使用string类型,表示消息类型(“publish”);
- transactionID:使用number类型表示事物ID;
- commandObject:对于publish消息,该部分为空,用null类型表示;
- publishName:发布的流的名称,使用string类型表示,比如我们发布到rtmp://192.168.1.101:1935/rtmp_live/test,则test为流名称,也可以省略,此时该字段为空字符;
- publishType:发布的流的类型,使用string类型表示,有3种类型,分别为live、record、append,record表示发布的视频流到rtmp服务器application对应的目录下会将发布的流录制成文件,append表示会将发布的视频流追加到原有的文件,如果原来没有文件就创建,live则不会在rtmp服务器上产生文件。
老规矩,我们看一下抓包文件:
通过抓包文件,我们可以看到这一抓包文件发送一条publish的消息,事务id为5,没有指定发布的流的名称,发布流的方式是live。如果发布的地址为rtmp://192.168.1.101:1935/rtmp_live,则其他任何客户端都可以访问该url获取视频资源,进而进行播放。
onStatus
客户端发送publish消息给rtmp服务端后,服务端会向客户端反馈一条消息,该消息采用了onStatus,onStatus的消息格式如下:
onStatus消息的组织结构如下:
onStatus消息由三部分组成:
- command Name:表示消息类型,恒为“onStatus”;
- transaction ID:设为0;
- command Object:用null表示;
- info Object:使用object类型表示多个字段,一般有warn,status,code,description等状态。
再看一下抓包文件:
该抓包文件使用onStatus返回了一条消息,描述的状态内容中code为NetStream.Publish.Start,description为Start publishing,该消息的目的就是告诉推流客户端,现在可以推流了。
SetDataFrame/OnMetaData
一般在客户端收到服务端返回的针对publish的onStatus消息之后,如果没有异常,推流端还会向服务器发送一条SetDataFrame的消息,其中包含onMetaData消息,这一条消息的主要作用是告诉服务端,推流段关于音视频的处理采用的一些参数,比如音频的采样率,通道数,帧率,视频的宽,高等信息。
我们来看一下消息的组织结构:
RTMP Body部分首先以AMF0格式(string)表示SetDataFrame消息;然后以AMF0格式编码(string)表示onMetaData消息;最后描述具体的关于音视频相关的参数,该部分使用ECMA Array的类型来表示。
我们来简单看下,首先看下SetDataFrame部分:
比较简单,就不详述了。
再看onMetaData部分,与SetDataFrame类似,贴一张图,大家可以体会得到熟悉的味道。
最后我们看一下property的部分:
ECMA Arrya本身的类型为0x08,其后紧跟着的是数组元素的个数,此处为20,占用4个字节表示,在之后便是具体的数组中的每一个元素。而数组中的每一个元素的具体编码方式又是遵循AMF0编码标准的。此例中,共表示了20个属性。包含文件大小,视频宽度和高度,视频编码codec_id,帧率信息,比特率信息,音频的codec_id,音频采样率,channel数量等,最后还有一个encoder字段来表示编码器,我们推流使用的是obs(open broad cast),所以该字段中表明了使用obs-output module,obs的版本号为25.0.0。
好了,接下来,就可以发送audio和video数据了,我们下面的文章继续了解一下video和audio数据的发送。欢迎继续关注,不要走开,精彩马上回来。