zoukankan      html  css  js  c++  java
  • flv视频网站进度条随意拖放

    需要确保三方面

    1.播放器要支持

    2.flv视频要有关键帧和meta信息

    3.服务器端要支持

    首先,播放器的问题。

    我用的播放器是flowplayer 3.2.7 下载地址:http://releases.flowplayer.org/flowplayer/flowplayer-3.2.7.zip 

    这个播放器默认是不支持拖放的,还需要插件,下载地址是:http://releases.flowplayer.org/flowplayer.pseudostreaming/flowplayer.pseudostreaming-3.2.7.zip

    解压之后,将插件文件夹里的两个flash文件拷到播放器文件夹下。

    然后将example文件夹下的javascript脚本改为如下情形

       <script>
          flowplayer("player", "../flowplayer-3.2.7.swf", {

              // configure clip to use "lighthttpd" plugin for providing video data
              clip: {
               url: 'http://pseudo01.hddn.com/vod/demo.flowplayervod/Extremists.flv',
            autoPlay:false , url: 't4.flv',
                  provider: 'lighttpd'
              },

              // streaming plugins are configured normally under the plugins node
              plugins: {
                  lighttpd: {
                      url: '../flowplayer.pseudostreaming-3.2.7.swf'
                  }
              }
          });
         
            </script>

    至此播放器支持了。

    2.给flv视频加入关键帧和meta信息

    需要一个完成此操作的工具,下载地址是http://www.blogjava.net/Files/xiaomage234/flvmeta.rar

    把插入关键帧的复选框选中,进行转换。

    3.这个好像跟服务器的操作系统有关系,我用的服务器操作系统是windows 2008 企业版。

    在视频网站根目录下新建文件夹App_Code(如果没有的话),然后加入以下脚本FLVStreaming.cs

    using System;
    using System.IO;
    using System.Web;

    public class FLVStreaming : IHttpHandler
    {
        private static readonly byte[] _flvheader = HexToByte("464C5601010000000900000009");

        public FLVStreaming()
        {
        }

        public void ProcessRequest(HttpContext context)
        {
            try
            {
                int pos;
                int length;

                // Check start parameter if present
                string filename = Path.GetFileName(context.Request.FilePath);

                using (FileStream fs = new FileStream(context.Server.MapPath(filename), FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    string qs = context.Request.Params["start"];

                    if (string.IsNullOrEmpty(qs))
                    {
                        pos = 0;
                        length = Convert.ToInt32(fs.Length);
                    }
                    else
                    {
                        pos = Convert.ToInt32(qs);
                        length = Convert.ToInt32(fs.Length - pos) + _flvheader.Length;
                    }

                    // Add HTTP header stuff: cache, content type and length       
                    context.Response.Cache.SetCacheability(HttpCacheability.Public);
                    context.Response.Cache.SetLastModified(DateTime.Now);

                    context.Response.AppendHeader("Content-Type", "video/x-flv");
                    context.Response.AppendHeader("Content-Length", length.ToString());

                    // Append FLV header when sending partial file
                    if (pos > 0)
                    {
                        context.Response.OutputStream.Write(_flvheader, 0, _flvheader.Length);
                        fs.Position = pos;
                    }

                    // Read buffer and write stream to the response stream
                    const int buffersize = 16384;
                    byte[] buffer = new byte[buffersize];
                   
                    int count = fs.Read(buffer, 0, buffersize);
                    while (count > 0)
                    {
                        if (context.Response.IsClientConnected)
                        {
                            context.Response.OutputStream.Write(buffer, 0, count);
          
          //Starts sending to client right away
          context.Response.Flush();
       
                            count = fs.Read(buffer, 0, buffersize);
                        }
                        else
                        {
                            count = -1;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.ToString());
            }
        }

        public bool IsReusable
        {
            get { return true; }
        }

        private static byte[] HexToByte(string hexString)
        {
            byte[] returnBytes = new byte[hexString.Length / 2];
            for (int i = 0; i < returnBytes.Length; i++)
                returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
            return returnBytes;
        }

    }
    然后在web.config文件里加入一下相应的节点


    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
        <system.webServer>
            <handlers>
                <add name="FLVStreaming" path="*.flv" verb="*" type="FLVStreaming" resourceType="Unspecified" preCondition="integratedMode" />
            </handlers>
        </system.webServer>
    </configuration>

    还有一点别忘了,要在MIME类型添加.flv  flv-application/octet-stream

    好了,这样就可以使用了。

    参考文献:http://archive.cnblogs.com/a/2017703/

              http://flowplayer.org/forum/5/14702

    Flv文件和Flash视频播放随着Youtube的流行,若干年前成为了网页视频播放的主流方案。当然,随着HTML和H264的普及,这个解决方案淡出也是迟早的事情了。但是作为这两天得折腾成功,还是把其中的一个典型问题记录在这里吧。

    1. 问题的产生

    Flash视频播放方案原理其实比较简单:网页端放置一个Flash编写的播放器,播放器通过http协议访问一个flv文件,通过Flash本身的视频解码功能进行视频播放。在播放过程中,为了视频的流畅播放器会对接下来要播放部分的数据做一些预读取。

    具体来说,我们只需要把flv文件放在网站目录下,让播放器指向这个地址就可以播放了。

    但是,这样制作好的播放器方案,在实际使用中会遇到一个问题:当用户拖动进度到还未缓冲的部分时,播放器会停止播放或者是回到视频的开始。这就是标题中的“对未缓冲进度条实现拖动”。

     

    2. 原理与解决

    设想一下,对于本地视频文件的拖动,播放器需要调用哪些接口才能实现呢?

    1. 通过某个API得知视频中某时刻对应的数据相对于文件头的偏移量;
    2. 通过某个API得到视频数据中指定偏移量以后的数据;
    3. 播放器本身要支持偏移访问和播放

    对于网络是视频,同样需要这两个关键的接口。很遗憾的,默认状态下(上面说的把flv文件直接放在IIS host的目录下)这两个条件都不具备。

    1. Flv文件一般不包含keyframe和meta信息。keyframe就是关键帧,而meta是元数据,通过它们,我们才能知道视频时间所对应的文件偏移量。
    2. IIS不提供文件位置偏移访问接口。

    如何是好呢?有条件要上,没有条件创造条件也要上!对于Flv文件,那当然是加上keyframe和meta就好,如何加法待会儿一一道来。对于文件偏移访问接口,有两个思路:

    1. 替换掉IIS,使用支持偏移访问的Flv嘛;
    2. 给IIS创造文件偏移访问的接口,iis extension、custom http handler和server side script都可以。

    3. 实现

    3.1 flv文件的meta生成

    上面提到,flv需要有meta信息才能正确地被分析并根据时间获取偏移量。有两个工具可以补全meta信息:

    两者都是命令行工具,也都有windows版本,下载了直接用就好。这里简单介绍一下用法:

    flvtool2:

    flvtool2 –U <input file> <output file>

    jamdi:

    jamdi –i <input file> –o <output file>

    如此,meta信息就补全了。

    3.2 使用IIS作为Web服务器的方法

    IIS是Windows默认Web服务器,在Windows下不用它很难(虽然不少装Apache的),而且尤其是当你的网站是ASP.net写成的话。上面说过,IIS默认是不支持文件偏移访问的,我们要创造条件让它能够支持。这里提供两种方法:

    3.2.1 Custom Http Handler

    给IIS置入一个Custom Http Handler,让它来处理所有对flv的请求,这就行了。简略的步骤是:

    1、使用任何一种CLR语言编写一个Custom Http Handler,这个Handler接受两个参数,第一个是flv文件名,第二个是start为参数名的偏移量,返回这个偏移量到文件尾的所有数据。

    2、将上面的Http Handler部署到IIS中。

    3、在IIS中将所有对.flv文件的访问定向到这个Custom Http Handler上。

    具体的步骤还是挺多,有人总结的很好,这里不再重复了。步骤和源代码在这里

    3.2.1 PHP代理

    当IIS已经配置好了PHP的时候,使用PHP代理也不失为一种简洁有效的方法了。这种方法的步骤非常简单:

    1、编写一个php页面,这个页面接受两个参数,第一个是文件名,第二个是start为参数名得偏移量,php读取flv文件并返回从偏移量到文件尾的数据。

    步骤相当简单,而且这个解决方案几乎是可以横跨所有Web Server和所有操作系统了,只要是能执行php的地方都可以应用。但是这种方法有两个缺点:

    • PHP的效率可能会有问题;
    • 对flv文件的位置有限制(这一点当你看了下面连接中的php代码以后就能了解)

    具体的PHP代码见这里

    3.3 使用其它Web服务器

    其实下面这些服务器都可以通过插件实现这功能:

    基本主流的Web Server都有支持了,不过基本也都要求在编译时通过开关把这部分包含进去。

    经过我的试验,最新的Nginx 1.0 for windows这个版本默认已经开启了这个开关,我们直接下载使用就好。既然标题上说的是“Windows服务环境下”,这里就大概说一下如何配置:

    1. nginx服务器下载最新的nginx 1.0 for windows,解压以后放置在某个目录下。
    2. nginx目前还没有写成windows服务,而只是应用程序。但是我们可以用这篇文章的办法,将它转变为一个服务。
    3. 在配置文件conf/nginx.conf中,添加如下语句:

    location ~ \.flv$ 

    flv; 
    }

    这里要注意,上面关于Nginx的参考文献中,这个配置写错了,将“flv;”写成了“.flv;”。

    3.4 播放器支持

    上面描述了服务端和视频所要实现的部分,最后一步是要一个支持拖动的flv播放器。这里推荐两个很成熟的播放器吧,他们对于非商业应用都是免费开源,而商业应用的价格也不贵:

    1. FlowPlayer:http://flowplayer.org/index.html
    2. JW Player:http://www.longtailvideo.com/support/jw-player/jw-player-for-flash-v5

    这两个播放器都有很详细的文档介绍如何支持所谓的流媒体(Flv streaming),也就是本文说的拖动。

    4. 其它

    本文介绍的解决方案,其实有很多种名字:

    • Flv(flash) Streaming
    • Pseudostreaming
    • Flv未缓冲视频拖动

    从第二个名字看来,它是一种“假”的流媒体。但是这种方案比起假设真的流媒体服务器并不逊色,不用架设专业甚至昂贵的流媒体服务器。也算是一种DIY的收获吧。

    其实FlowPlayer的网站上也有一篇非常详细的综述性质的文章,可以和本文互为参考。

    另外,对于高清视频,H264有一个比较统一的解决方案(IIS、Nginx、Apache、Lighttpd全机种制霸了),不用像flv这么折腾,具体参考这里

    5. 参考文献

     
     
     
     
     
  • 相关阅读:
    Dig out deleted chat messages of App Skype
    Search history in "Maps"
    如何对具有端点加密功能的LINE进行取证
    HttpHandler实现网页图片防盗链
    自定义文本验证控件
    MySQL查询本周、上周、本月、上个月份数据的sql代码
    org.hibernate.NonUniqueObjectException
    Struts2 中的值栈的理解
    struts2中struts.xml配置文件详解
    基于Struts自定义MVC-2
  • 原文地址:https://www.cnblogs.com/yibinboy/p/2610620.html
Copyright © 2011-2022 走看看