AMFObject 数据格式浅析
amf.h中关于 AMFObject 是这样的定义的:
typedef struct AMFObject
{
int o_num;
struct AMFObjectProperty *o_props;
} AMFObject;
有里面变量可知 o_num 代表 o_props的个数;
在rtmp.c里有这样一段使用在
static int HandleInvoke(RTMP *r, const char *body, unsigned int nBodySize)
{
AMFObject obj;
AVal method;
AVal method11;
int txn;
int ret = , nRes;
if (body[] != 0x02) /* make sure it is a string method name we start with */
{
//RTMP_Log(RTMP_LOGWARNING, "%s, Sanity failed. no string method in invoke packet", __FUNCTION__);
return ;
} nRes = AMF_Decode(&obj, body, nBodySize, FALSE);
if (nRes < )
{
//RTMP_Log(RTMP_LOGERROR, "%s, error decoding invoke packet", __FUNCTION__);
return ;
} AMF_Dump(&obj);
AMFProp_GetString(AMF_GetProp(&obj, NULL, 0), &method);
.....
.....
}
在此函数内 AMFObject obj;通过 nRes = AMF_Decode(&obj, body, nBodySize, FALSE); 会对body进行AMF解码相当于给obj进行赋值,然后通过AMF_Dump(&obj) 应该是进行一个解析?(最下面会贴出该函数的源码)
经过AMF_Dump()之后,会获通过 AMFProp_GetString(AMF_GetProp(&obj, NULL, 0), &method); 获取信令的操作。当然也可以自定义他们的操作,类似于:
static const AVal av_NetStream_Pause_Notify = AVC("NetStream.Pause.Notify");
static const AVal av_NetStream_Play_UnpublishNotify = AVC("NetStream.Play.UnpublishNotify");
//................
下面代码会根据method的内容进行相应的操作。
-----------------------------------------------
扯的有点偏了,这里还是 讲AMFObject 上面的操作经过抓包可以看一下大致的内容:

===================================================
由包里的内容此次信令操作为自定义的“NoticeNotify”,而obj相当于一个容器,里面就有上面标识的3项内容,也就是根据AMFObject 的数据结构可知:
o_num 个数为3 项 o_props 内容。而 o_props 的数据结构为:
typedef struct AMFObjectProperty
{
AVal p_name;
AMFDataType p_type;
union
{
double p_number;
AVal p_aval;
AMFObject p_object;
} p_vu;
int16_t p_UTCoffset;
} AMFObjectProperty;
其中 o_props 里有个“联合”数据结构成员,从上面抓包的内容来看其中的三项,也很好的解释了其中三项的内容。
第一项:type 为string 对应 AVal 类似于 key-value
第二项:type 为Number 对应 double。
第三项:type 也为string 对应 AVal。
这样来看如果想取obj里的内容就比较好取了。
其中obj的成员 o_props 就是一个类似数组,在操作的时候可以 obj->o_props[index];
或者再细一点就是 obj->o_props[index].p_type;
=====================================
总结的比较乱,因为现在对amf还不是很了解,不过对于amf真的可以花些时间去分析一下它的博大精深。
再此贴一下AMF_Dump()的源码:
void
AMFProp_Dump(AMFObjectProperty *prop)
{
char strRes[];
char str[];
AVal name; if (prop->p_type == AMF_INVALID)
{
//RTMP_Log(RTMP_LOGDEBUG, "Property: INVALID");
return;
} if (prop->p_type == AMF_NULL)
{
//RTMP_Log(RTMP_LOGDEBUG, "Property: NULL");
return;
} if (prop->p_name.av_len)
{
name = prop->p_name;
}
else
{
name.av_val = "no-name.";
name.av_len = sizeof("no-name.") - ;
}
if (name.av_len > )
name.av_len = ; snprintf(strRes, , "Name: %18.*s, ", name.av_len, name.av_val); if (prop->p_type == AMF_OBJECT)
{
//RTMP_Log(RTMP_LOGDEBUG, "Property: <%sOBJECT>", strRes);
AMF_Dump(&prop->p_vu.p_object);
return;
} switch (prop->p_type)
{
case AMF_NUMBER:
snprintf(str, , "NUMBER:\t%.2f", prop->p_vu.p_number);
break;
case AMF_BOOLEAN:
snprintf(str, , "BOOLEAN:\t%s",
prop->p_vu.p_number != 0.0 ? "TRUE" : "FALSE");
break;
case AMF_STRING:
snprintf(str, , "STRING:\t%.*s", prop->p_vu.p_aval.av_len,
prop->p_vu.p_aval.av_val);
break;
case AMF_DATE:
snprintf(str, , "DATE:\ttimestamp: %.2f, UTC offset: %d",
prop->p_vu.p_number, prop->p_UTCoffset);
break;
default:
snprintf(str, , "INVALID TYPE 0x%02x", (unsigned char)prop->p_type);
} //RTMP_Log(RTMP_LOGDEBUG, "Property: <%s%s>", strRes, str);
}
AMFObject 数据格式浅析的更多相关文章
- 【原】AMFObject数据格式详解
AMF AMF是Action Message Format(动作消息格式)的简写,它是一种二进制的数据格式.它的设计是为了把actionscript里面的数据(包括Object, Array, Boo ...
- netty5 HTTP协议栈浅析与实践
一.说在前面的话 前段时间,工作上需要做一个针对视频质量的统计分析系统,各端(PC端.移动端和 WEB端)将视频质量数据放在一个 HTTP 请求中上报到服务器,服务器对数据进行解析.分拣后从不同的 ...
- 浅析WebGIS
浅析WebGIS 摘要:随着网络的发展,利用Web公布信息越来越普及化.而地理信息系统(GIS)与网络的结合就产生了万维网地理信息系统(WebGIS),它引起了地理信息公布的新的变革,对实现GIS信息 ...
- 浅析深究什么是SOA?
浅析深究什么是SOA? http://blog.vsharing.com/fengjicheng/A1059842.html 金蝶中间件有限公司总经理 奉继承 博士 阅读提示: 本文探讨SOA概念背后 ...
- 内存管理 & 内存优化技巧 浅析
内存管理 浅析 下列行为都会增加一个app的内存占用: 1.创建一个OC对象: 2.定义一个变量: 3.调用一个函数或者方法. 如果app占用内存过大,系统可能会强制关闭app,造成闪退现象,影响用户 ...
- 用Python浅析股票数据
用Python浅析股票数据 本文将使用Python来可视化股票数据,比如绘制K线图,并且探究各项指标的含义和关系,最后使用移动平均线方法初探投资策略. 数据导入 这里将股票数据存储在stockData ...
- 浅析MVC模式与三层架构的区别
浅析MVC模式与三层架构的区别 三层架构和MVC是有明显区别的,MVC应该是表现模式(三个加起来以后才是三层架构中的UI层).三层架构(3-tier application) 通常意义上的三层架构就是 ...
- 浅析 Bigtable 和 LevelDB 的实现
在 2006 年的 OSDI 上,Google 发布了名为 Bigtable: A Distributed Storage System for Structured Data 的论文,其中描述了一个 ...
- 浅析 Linux 中的时间编程和实现原理一—— Linux 应用层的时间编程【转】
本文转载自:http://www.cnblogs.com/qingchen1984/p/7007631.html 本篇文章主要介绍了"浅析 Linux 中的时间编程和实现原理一—— Linu ...
随机推荐
- ARM汇编指令集3
常用ARM指令1:数据处理指令 •数据传输指令 mov mvn mov r1, r0 @两个寄存器之间数据传递 mov r1, #0xff ...
- R语言:数据的分割-计算-整合(split-apply-aggregate)
当获取到原始数据时,我们通常的做法是对该数据进行分割成小片段,然后对各小片段进行计算统计,最后整合成最终的数据.这是统计学里数据处理的一般规律. R语言为我们提供了相应的函数来分别处理这三个阶段任务. ...
- Spring核心AOP(面向切面编程)总结
(尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/75208354冷血之心的博客) 1.AOP概念: 面向切面编程,指扩 ...
- Android 进阶13:几种进程通信方式的对比总结
不花时间打基础,你将会花更多时间解决那些不必要的问题. 读完本文你将了解: RPC 是什么 IDL 是什么 IPC 是什么 Android 几种进程通信方式 如何选择这几种通信方式 Thanks RP ...
- Android 进阶7:进程通信之 AIDL 的使用
读完本文你将了解: AIDL 是什么 AIDL 支持的数据类型 AIDL 如何编写 AIDL 实例 创建 AIDL 编写服务端代码 编写客户端代码 运行结果 总结 代码地址 Thanks 记得 201 ...
- Ubuntu16.04配置apache+php+mysql
命令行配置apache input sudo apt-get install apache2 done! 命令行配置mysql 参见: MySQL install and setting 命令行配置p ...
- 解决cookies取值中文乱码问题
存入cookie 取出cookie 分别需要编码和解码, 注:要统一
- Linux部分常用命令学习(二)
1.wc:wc命令是一个统计的工具,主要用来显示文件所包含的行.字和字节数.wc命令是word count的缩写. 命令格式:wc [选项参数] [文件] 选项参数: -c 统计字节数 -l 统计行数 ...
- POJ1160 Post Office (四边形不等式优化DP)
There is a straight highway with villages alongside the highway. The highway is represented as an in ...
- MySql必知必会实战练习(六)游标
游标主要用于交互式应用,滚动屏幕上的数据,并对数据进行浏览或做出更改 看一下下面的例子: drop procedure IF EXISTS processorders; create procedur ...