FLV格式解析及其解析器的实现

FLV格式解析及其解析器的实现一、FLV基础入门最近在搞flv解析器,网站看到一些比较好的基础入门资料,直接搬过来了FLV文件格式详解FLV文件格式解析FLV封装原理flv文件元信息(metadata)FLV文件结构解析其实看这么多资料还不如下载一个flv解析器(flvparse)直接看里面的格式,heard、tag应有尽有,一目了然二、FLV解析器实现在对flv格式清楚的基础上,就…

一、FLV基础入门

最近在搞flv解析器,网站看到一些比较好的基础入门资料,直接搬过来了
FLV文件格式详解
FLV文件格式解析
FLV封装原理
flv文件元信息(metadata)
FLV文件结构解析

其实看这么多资料还不如下载一个flv解析器(flvparse)直接看里面的格式,heard、tag应有尽有,一目了然
这里写图片描述

二、FLV解析器实现

在对flv格式清楚的基础上,就可以实现一个flv简单解析器,思路很简单,就是对一段数据按照flv约定“协议”慢慢翻译就行,我在里面记录几个小技巧:

1、读取1字节、2字节、3字节、4字节或者8字节的16进制转化成一个整数值
宏实现
#define FLV_UI32(x) (unsigned int)(((*(x)) << 24) + ((*(x + 1)) << 16) + ((*(x + 2)) << 8) + (unsigned char)(*(x + 3)))
#define FLV_UI24(x) (unsigned int)(((*(x)) << 16) + ((*(x + 1)) << 8) + (unsigned char)(*(x + 2)))
#define FLV_UI16(x) (unsigned int)(((*(x) ) << 8) + (unsigned char)(*(x + 1)))
#define FLV_UI8(x) (unsigned int)(*(x))
代码实现
static unsigned int read_8(unsigned char const* buffer) {
    return buffer[0];
}

static uint16_t read_16(unsigned char const* buffer) {
    return (buffer[0] << 8) | (buffer[1] << 0);
}

static unsigned int read_24(unsigned char const* buffer) {
    return (buffer[0] << 16) | (buffer[1] << 8) | (buffer[2] << 0);
}

static uint32_t read_32(unsigned char const* buffer) {
    return (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8)
            | (buffer[3] << 0);
}

static uint64_t read_64(unsigned char const* buffer) {
    return ((uint64_t) (read_32(buffer)) << 32) + read_32(buffer + 4);
}
2、flv解析meta数据的时候, 8字节的16进制怎么转化成一个double类型浮点数(比如图中width:640.0)

这里写图片描述
网上没有现成的工具,就可以灵活的C语言解析-利用union共用体(注意16进制的转化和大小端)

int readFLVDouble() {

       double value;
        union{
               unsigned char dc[8];
               double dd;
         }d;

        d.dc[0] = 0;
        d.dc[1] = 0;
        d.dc[2] = 0;
        d.dc[3] = 0;
        d.dc[4] = 0;
        d.dc[5] = 0;
        d.dc[6] = 132;
        d.dc[7] = 64;

        value = d.dd;

        printf("value = %lf\n", value);

        return 8;
}
3.flv格式被恶意制造,可能会让你的代码core掉,所以要增加保护手段(

修改flv的meta的某个变量值很容易
这里写图片描述
我们一般以为flv的格式这些一定是正确的,但是网络环境下真的说不来,万一转码的时候转错或者其他恶意制造,我们就发生过这样的core———flv媒体拖拽core,解析len错误,导致memcpy拷贝了一大片内存,代码如下

int CFlvReader::readFLVScriptDataString(unsigned char* buf, char **s, int* len)
{
    *len = FLV_UI16(buf);
    //printf("len 1=%d\n",*len);

    memcpy((unsigned char*)*s, buf+sizeof(uint16_t), *len);
    return *len + sizeof(uint16_t);
}

所以解析*data的时候,每一移动一个字节就需要判断到底有么有在末尾,一定要增加保护机制,涉及的重复代码比较多,就可以通过宏来实现。

#define FLV_DATA_MOVE_OFFSET_CHK(flv_buf, flv_buf_len, move_len)\ do{ 
                                                                \       if(move_len < 0 || flv_buf_len < move_len){ 
                  \          return FLV_METATAG_META_ERROR;                         \       }                                                         \       flv_buf += move_len;                                      \       flv_buf_len -= move_len;                                  \ }while(0)

三、视频转化原理

编码格式就是编码器输出的“裸”的视频流和音频流,常见的视频编码格式就是H.264,常见的音频编码格式是AAC和MP3
FLV是一种文件封装格式,它可以封装H264和AAC,其他常见的文件封装格式还有MP4、TS、MKV等等,不同文件封装格式可以相互转化,只要把一种文件封装格式拆包,解出“裸”的视频流和音频流,在安装另外一直文件封装格式打包即可

四、媒体拖拽

现在各大视频网站都支持媒体拖拽,而主要视频格式是mp4、ts、flv

1、hls媒体推拽原理

http live streaming : 由苹果公司推出的一个流媒体网络传输协议, 该技术在最大的优势就是自适应码率流播
使使 效 果 就 是 客 户 端 会 根 据 网 络 状 况 自 动 选 择 不 同 码 率 的 视 频 流 , 条 件 允 许 的 情 况 下 使 用 高 码 率 , 网 络 繁 忙 的 时 候 使 用 低 码 率
并 且 自 动 在 二 者 间 随 意 切 换 。 这 对 移 动 设 备 网 络 状 况 不 稳 定 的 情 况 下 保 障 流 畅 播 放 非 常 有 帮 助 。
实 现 方 法 是 服 务 器 端 提 供 多 码 率 视 频 流 , 并 且 在 列 表 文 件 中 注 明 , 播 放 器 根 据 播 放 进 度 和 下 载 速 度 自 动 调 整
特点是将流媒体切分为若干 TS 片段(比如每10秒一段),然后通过一个扩展的 m3u 列表文件将这些 TS 片段集中起来供客户端播放器接收。HTTP Live Streaming 则只需要根据列表文件中的时间轴找出对应的 TS 片段下载即可,不需要 range request,对服务器的要求小很多。
mp4range 如 果 是 m p 4 格 式 , 当 你 媒 体 拖 拽 的 时 候 就 需 要 服 务 器 支 持 让 r a n g e 请 求
chrome(pc)还不支持HLS(m3u8)

2、flv媒体拖拽

flv的媒体拖拽可以分为 时 间 拖 拽 和 字 节 拖 拽
这个实现可以利用yamdi.exe给flv视频添加关键帧信息: 关于关键帧的信息,有两个数组,times和filepositions,这两个数组是相对应的,比如times[10]=184.4,而filepositions[10]=10000,意思是视频在184.4秒处的文件位置是10000。比如请求
wget -S –limit-rate=1M -e http_proxy=http://127.0.0.1:8080http://flv.vaynedu.com/3.flv?start=10000
则视频就会从184.4秒处开始播放,这样就实现了seek到184.4的效果。但是需要注意的是,start的数值必须是关键帧数组里的filepositions的值,否则不会成功。

给flv添加关键帧 这个网站免费下载而且还有教程,不用跑到csdn花费积分

无关键帧的的flv meta信息如图
这里写图片描述

有关键帧的的flv meta信息如图
这里写图片描述

有关键帧的在里面增加了不少信息

有什么问题,欢迎大家交流

今天的文章FLV格式解析及其解析器的实现分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/24578.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注