当前流行的视频网站,关于视频的在线拖动观看技术的小试,
1.flv文件
flv视频文件,想大家都比较清楚,只要从关键帧的位置切开,并加上"FLV\x1\x1\0\0\0\x9\0\0\0\x9"公共头标志信息,后对任何支持flv视频文件dencoder的播放器都是可以正常播放的
"FLV\x1\x1\0\0\0\x9\0\0\0\x9" + keyframe(body)
2.lighttpd中的mod_flv_streaming.c模块 (重点)
http://www.lighttpd.net/
http://blog.lighttpd.net/articles/2006/03/09/flv-streaming-with-lighttpd
这里通过http的get方法,向服务器请求指定的视频片段
形如: http://youserver.com/flv/abcdefg.flv?start=12345
mod_flv_streaming.c默认的方式是,从start(文件的物理位置offset)的开始,默认到文件结束。
相关服务器代码如下:
for (k = 0; k < p->conf.extensions->used; k++) {
data_string *ds = (data_string *)p->conf.extensions->data[k];
int ct_len = ds->value->used - 1;
if (ct_len > s_len) continue;
if (ds->value->used == 0) continue;
if (0 == strncmp(con->physical.path->ptr + s_len - ct_len, ds->value->ptr, ct_len)) {
data_string *get_param;
stat_cache_entry *sce = NULL;
buffer *b;
int start;
char *err = NULL;
/* if there is a start=[0-9]+ in the header use it as start,
* otherwise send the full file */
array_reset(p->get_params);
buffer_copy_string_buffer(p->query_str, con->uri.query);
split_get_params(p->get_params, p->query_str);
/*这个是重点,获得客户端的播放器通过get方法传来的start(文件拖动的开始位置offset)*/
if (NULL == (get_param = (data_string *)array_get_element(p->get_params, "start"))) {
return HANDLER_GO_ON;
}
/* too short */
if (get_param->value->used < 2) return HANDLER_GO_ON;
/* check if it is a number */
start = strtol(get_param->value->ptr, &err, 10);
if (*err != '\0') {
return HANDLER_GO_ON;
}
if (start <= 0) return HANDLER_GO_ON;
/* check if start is > filesize */
if (HANDLER_GO_ON != stat_cache_get_entry(srv, con, con->physical.path, &sce)) {
return HANDLER_GO_ON;
}
if (start > sce->st.st_size) {
return HANDLER_GO_ON;
}
/* we are safe now, let's build a flv header */
b = chunkqueue_get_append_buffer(con->write_queue);
/*准备发送给客户端播放器的flv公共头信息13字节*/
buffer_copy_string_len(b, CONST_STR_LEN("FLV\x1\x1\0\0\0\x9\0\0\0\x9"));
/*发送seek到的拖动关键桢的位置keyframe, 并计算出从拖动点到该视频文件结束的长度*/
http_chunk_append_file(srv, con, con->physical.path, start, sce->st.st_size - start);
/* http相关信息的填充*/
response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("video/x-flv"));
con->file_finished = 1;
/*done, 处理拖动完成*/
return HANDLER_FINISHED
3 对客户端的播放器而言,服务器对flv文件的拖动支持是透明的,
只要播放器安照合法的get方法向服务器请求,即可得到可以播放的视频片段,
但是这里的start=xxxx,一定是flv视频文件的关键桢位置,否则不能播放
一般而言,对flv视频文件可以使用
yamdi
http://yamdi.sourceforge.net/
加上metadata信息,即可完美支持拖动,
播放器可以再第一次请求视频文件的时候获得该视频的metadata信息(即包含关键桢,时间,等等与视频相关的信息)
4.以上讨论的,都是lighttpd-mod_flv_streaming.c默认的对flv的拖动支持,
其实可以,做一些简单的扩展,
可以增加end参数,即是增加拖动的结束参数,
假设,很多用户并不会观看视频到结束,
每次请求N字节
http://youserver.com/flv/abcdefg.flv?start=23456&end=23456+N
播放器可以增加这样的功能,
a.先请求某一段视频
b.当当前视频片段没有播放完毕之前,不会去请求下一个片段,
只有当当前视频片段在即将播放结束的时候,再去请求下一个片段,
这样,当用户,看了前面的某一片段后,突然关闭该播放页,以至于不会白白浪费掉那已经download到本地,但是并没有观看的视频,节余带宽
粗略代码实现如下:
if (NULL != (get_param = (data_string *)array_get_element(p->get_params, "start")))
{
/* too short */
if (get_param->value->used < 2)
return HANDLER_GO_ON;
/* check if it is a number */
start = strtol(get_param->value->ptr, &err, 10);
if (*err != '\0')
{
return HANDLER_GO_ON;
}
/* check if tflvbegin is >= 0 */
if (start < 0)
return HANDLER_GO_ON;
/* check if start is > filesize */
if (start > sce->st.st_size)
{
return HANDLER_GO_ON;
}
}
else
{
return HANDLER_GO_ON;
}
/* if there is a start=[0-9]+ in the header use it as end,
* otherwise send the full file */
/*这里重点,仿照lighttpd如何获得get方法的中的start,同理获得end参数, 并做一些必要的合法性检查*/
if (NULL != (get_param = (data_string *)array_get_element(p->get_params, "end")))
{
/* too short */
if (get_param->value->used < 2)
return HANDLER_GO_ON;
/* check if it is a number */
end = strtol(get_param->value->ptr, &err, 10);
if (*err != '\0')
{
return HANDLER_GO_ON;
}
/*参数检查,必须*/
/* check if end is > 0
* check if start < end
* make sure star > 0
* */
if (end <= 0 || start >= end)
return HANDLER_GO_ON;
/* check if end is > filesize */
if (end > sce->st.st_size)
{
//return HANDLER_GO_ON;
tflvend = sce->st.st_size; /* path tflvend is not right */
}
}
else
{
return HANDLER_GO_ON;
}
/* we are safe now, let's build a flv header */
b = chunkqueue_get_append_buffer(con->write_queue);
/*准备发送给客户端播放器的flv公共头信息13字节*/
buffer_copy_string_len(b, CONST_STR_LEN("FLV\x1\x1\0\0\0\x9\0\0\0\x9"));
/*这个是重点,以前默认的是发送的数据长度是用 fileseize-start, 现在要用end替代filesize, 即是 end-start*/
http_chunk_append_file(srv, con, con->physical.path, start, end - start);
response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("video/x-flv"));
con->file_finished = 1;
return HANDLER_FINISHED
-------------------------------------
gamil:bychyahoo@gmail.com
分享到:
相关推荐
web_share通过Lighttpd分享文件,实现上传下载为什么用Lighttpd?因为它安装包小……为什么这么简陋?因为我菜。欢迎提PR来帮助我改进。这个项目意义何在?帮助不同设备之间传输文件。举个例子:手机和电脑要传文件...
Lighttpd是一个德国人领导的开源软件,其根本的目的是提供一个专门针对高性能网站,安全、快速、兼容性好并且灵活的web server环境。具有非常低的内存开销,cpu占用率低,效能好,以及丰富的模块等特点。lighttpd是...
使用lighttpd的开源代码成功搭建支持cgi的代码包
包括lighttpd.conf配置文件以及用于控制web server启动和停止的脚本。
主要内容包括:lighttpd介绍与分析准备工作、lighttpd网络服务主模型、lighttpd数据结构、伸展树、日志系统、文件状态缓存器、配置信息加载、i/o多路复用技术模型、插件链、网络请求服务响应流程、请求响应数据快速...
lighttpd完全学习,适合新手文档参考,ppt文件
lighttpd.conf,可以直接使用。带注释。网上搜索的资料,自己加的。可能有人觉得没什么用╮(╯_╰)╭。分享
lighttpd h264带h264支持补丁,可以支持mp4在线播放,并实现快进等播放控制,默认的lighttpd是不支持快进的
Lighttpd源码分析就是一本介绍分析Lighttpd源码的初级读本,其主要目标在于:一方面让已经接触过网络编程的读者可以从Lighttpd这个开源项目中学习到更深入实际的网络编程知识,另一方面也可以让使用Lighttpd作为自己...
lighttpd-1.4.20.tar lighttpd-1.4.20.tar
lighttpd 流程分析工作模式,帮助理解lighttpd
varnish+lighttpd配置
lighttpd-1.4.20源码看了很久了,学习总结本来早就该写了的,只是人懒得很,拖拖拉拉到现在,如果各位看了觉得多少还有那么一点点帮助,我就继续来(当然,总结的东东还是会发在这个帖子内)。 预计总共将有15个...
之前2013年上传了编译好的执行文件,现在上传代码。虽然很久远,或许有人还能用的上。 参考了网上的一些资源和信息, lighttpd是自己编译出来的,有代码。php-cgi是网上下载,合起来可以在android上使用。 里面也...
lighttpd-1.4.26 源码,官方直接下载,学习的好资源。
如何在ubuntu上实现lighttpd 1、下载mongoose使用mongoose中的example中的websocket_chat,实现websocket 2、websocket_chat源码下载路径 官网:https://cesanta.com 论坛:...
lighttpd代码阅读资料 参数的 web服务器
最新lighttpd-1.4.28源码下载最新lighttpd-1.4.28源码下载最新lighttpd-1.4.28源码下载最新lighttpd-1.4.28源码下载最新lighttpd-1.4.28源码下载最新lighttpd-1.4.28源码下载
自己在cygwin下编译的源码,并指定的默认配置文件路径和lib路径, 编译环境windows xp 32位 gcc version 4.9.2 (GCC) 编译参数: ./configure --prefix=XXXX --without-bzip2 配置文件为从源码dco/config目录获取后...
lighttpd-1.4.20-cmake