http://blog.lighttpd.net/articles/2006/03/09/flv-streaming-with-lighttpd
http://www.flashcomguru.com/index.cfm/2006/6/18/lightyupdate
flv streaming
High performance flv-streaming with lighttpd is possible since lighttpd 1.4.11.
With lighty you can easily handle 10000 parallel downloads of your movies including protection against hot-linking with mod_secdownload. This is basicly all you need to build the free video.google.com for yourself.
Just add this you your lighttpd.conf and restart the server:
server.modules = ( ..., "mod_flv_streaming", ... )
flv-streaming.extensions = ( ".flv" )
Players
mod_flv_streaming expects you to fetch the flv-file with a GET parameter if you want to do a seek into the file.
GET /movie.flv?start=23 HTTP/1.1
Host: ...
•Fabian Topfstedt has done this for us. Get his player and place it in the webfolder. To use the player you have include this piece of HTML:
 <object
   classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
   codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,19,0"
   width="336"
   height="297">
   <param name="movie" value="scrubber.swf?file=/movie.flv" />
   <param name="quality" value="high" />
   <embed src="scrubber.swf?file=/movie.flv"
     quality="high"
     pluginspage="http://www.macromedia.com/go/getflashplayer"
    type="application/x-shockwave-flash"
     width="336"
     height="297"></embed>
 </object>
•for the RMP you can use a simple rewrite to get it working with mod_flv_streaming
url.rewrite = (
 "^/name-of-php-script.php\?file=(.+)&position=0___FCKpd___3quot; => "/$1",
 "^/name-of-php-script.php\?file=(.+)&position=([0-9]+)___FCKpd___3quot; => "/$1?start=$2",
)
encoding flash movies
As example I took a video from Ryan Wiebers page about Saber-Effects.
The .mov file was converted into a .flv with the help of ffmpeg and indexed with flvtool2.
$ wget http://ryanw.michaelfrisk.com/ryan-w/clips/kid_fight.mov
$ ffmpeg -i kid_fight.mov kid_fight.flv
$ flvtool2 -U kid_fight.flv-------------------------------------------当前流行的视频网站,关于视频的在线拖动观看技术的小试, 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)的开始,默认到文件结束。      相关服务器代码如下:
C代码
1.for (k = 0; k < p->conf.extensions->used; k++) {

2.        data_string *ds = (data_string *)p->conf.extensions->data[k];

3.        int ct_len = ds->value->used - 1;

4.  
5.        if (ct_len > s_len) continue;  
6.        if (ds->value->used == 0) continue;  
7.  
8.        if (0 == strncmp(con->physical.path->ptr + s_len - ct_len, ds->value->ptr, ct_len)) {

9.            data_string *get_param;  
10.            stat_cache_entry *sce = NULL;  
11.            buffer *b;  
12.            int start;

13.            char *err = NULL;  
14.            /* if there is a start=[0-9]+ in the header use it as start,

15.             * otherwise send the full file */  
16.  
17.            array_reset(p->get_params);  
18.            buffer_copy_string_buffer(p->query_str, con->uri.query);

19.            split_get_params(p->get_params, p->query_str);

20./*这个是重点,获得客户端的播放器通过get方法传来的start(文件拖动的开始位置offset)*/  
21.            if (NULL == (get_param = (data_string *)array_get_element(p->get_params, "start"))) {  
22.                return HANDLER_GO_ON;  
23.            }  
24.  
25.            /* too short */  
26.            if (get_param->value->used < 2) return HANDLER_GO_ON;  
27.  
28.            /* check if it is a number */  
29.            start = strtol(get_param->value->ptr, &err, 10);

30.            if (*err != '\0') {  
31.                return HANDLER_GO_ON;  
32.            }  
33.  
34.            if (start <= 0) return HANDLER_GO_ON;  
35.  
36.            /* check if start is > filesize */  
37.            if (HANDLER_GO_ON != stat_cache_get_entry(srv, con, con->physical.path, &sce)) {

38.                return HANDLER_GO_ON;  
39.            }  
40.  
41.            if (start > sce->st.st_size) {

42.                return HANDLER_GO_ON;  
43.            }  
44.  
45.            /* we are safe now, let's build a flv header */  
46.            b = chunkqueue_get_append_buffer(con->write_queue);

47.                          
48.                        /*准备发送给客户端播放器的flv公共头信息13字节*/  
49.            buffer_copy_string_len(b, CONST_STR_LEN("FLV\x1\x1\0\0\0\x9\0\0\0\x9"));  
50.                          
51.                        /*发送seek到的拖动关键桢的位置keyframe, 并计算出从拖动点到该视频文件结束的长度*/  
52.            http_chunk_append_file(srv, con, con->physical.path, start, sce->st.st_size - start);

53.                       /* http相关信息的填充*/  
54.            response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("video/x-flv"));  
55.  
56.            con->file_finished = 1;  
57.                       /*done, 处理拖动完成*/  
58.            return HANDLER_FINISHED  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到本地,但是并没有观看的视频,节余带宽   粗略代码实现如下:

C代码

   1.  
   2.if (NULL != (get_param = (data_string *)array_get_element(p->get_params, "start")))    
   3.{  
   4.  
   5.    /* too short */  
   6.    if (get_param->value->used < 2)

   7.                    return HANDLER_GO_ON;  
   8.  
   9.                /* check if it is a number */  
   10.                start = strtol(get_param->value->ptr, &err, 10);

   11.                if (*err != '\0')    
   12.                {  
   13.                    return HANDLER_GO_ON;  
   14.                }  
   15.                  
   16.                /* check if tflvbegin is >= 0 */  
   17.                if (start < 0)    
   18.                    return HANDLER_GO_ON;  
   19.  
   20.                /* check if start is > filesize */  
   21.                if (start > sce->st.st_size)

   22.                {  
   23.                    return HANDLER_GO_ON;  
   24.                }  
   25.            }  
   26.            else

   27.            {  
   28.                return HANDLER_GO_ON;  
   29.            }  
   30.                          
   31.            /* if there is a start=[0-9]+ in the header use it as end,

   32.             * otherwise send the full file */  
   33./*这里重点,仿照lighttpd如何获得get方法的中的start,同理获得end参数, 并做一些必要的合法性检查*/  
   34.            if (NULL != (get_param = (data_string *)array_get_element(p->get_params, "end")))    
   35.            {  
   36.                /* too short */  
   37.                if (get_param->value->used < 2)

   38.                    return HANDLER_GO_ON;  
   39.  
   40.                /* check if it is a number */  
   41.                end = strtol(get_param->value->ptr, &err, 10);

   42.                if (*err != '\0')    
   43.                {  
   44.                    return HANDLER_GO_ON;  
   45.                }  
   46.  
   47.                /*参数检查,必须*/  
   48.                /* check if end is > 0

   49.                 * check if start < end

   50.                 * make sure star > 0

   51.                 * */  
   52.                if (end <= 0 || start >= end)

   53.                    return HANDLER_GO_ON;  
   54.  
   55.                /* check if end is > filesize */  
   56.                if (end > sce->st.st_size)

   57.                {  
   58.                    //return HANDLER_GO_ON;

   59.                    tflvend = sce->st.st_size; /* path tflvend is not right */  
   60.                }  
   61.            }  
   62.            else

   63.            {  
   64.                return HANDLER_GO_ON;  
   65.              
   66.      
   67.   }  
   68.  
   69./* we are safe now, let's build a flv header */  
   70.            b = chunkqueue_get_append_buffer(con->write_queue);

   71.                          
   72.                        /*准备发送给客户端播放器的flv公共头信息13字节*/  
   73.            buffer_copy_string_len(b, CONST_STR_LEN("FLV\x1\x1\0\0\0\x9\0\0\0\x9"));  
   74.  
   75.                      /*这个是重点,以前默认的是发送的数据长度是用 fileseize-start, 现在要用end替代filesize, 即是 end-start*/  
   76.            http_chunk_append_file(srv, con, con->physical.path, start, end - start);

   77.            response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("video/x-flv"));  
   78.            con->file_finished = 1;  
   79.            return HANDLER_FINISHED
2d102efffe0a74c16d06d66c1e5dbf8920090820120955.zip (您是游客您没有权限下载)