HTTP协议下可拖动时间轴播放FLV的实现(伪流媒体)

HTTP协议下实现FLV的播放其实并不复杂,当初实现的原理是使用了flowPlayer插件实现的,效果还不错。但仍有两大问题影响着客户的访问情绪:

1.预加载时页面卡死,似乎没有边下边播。

2.偶尔边下边播,却无法拖动时间轴至未下载的部分。相信很多人也遇到该问题。

一度想采用专门的媒体服务器如Adobe的FMS去实现该功能,后多方查找资料,发现采用媒体服务器成本较高,且效率并不是很好,各大视频网站也未采用该方式。而实现HTTP协议下播放flv并可拖动时间轴并非没有可能,关键在于以下几点:

  1. Flv视频文件包含metadata信息,大多数转码工具生成的FLV不包含该信息。可用工具增加(flvtool2,yamdi[速度很快,效率高])。
  2. Web端播放器需支持拖动时间轴时发送请求的连接中带有字节参数,或时间参数。
  3. 服务器端实现对flv文件的读取和流式输出。

一、给FLV文件加入metadata信息

flvtool2和yamdi都可以实现该功能,但yamdi工具的效率要高出很多,400M左右的FLV处理时间大概2分钟,推荐使用。实现方式是在cmd命令窗口下执行如下命令:

yamdi -i 源文件名 -o 新文件名

二、flowPlayer的使用与配置

flowPlayer是一款web端播放flv等视频的利器,功能比较强大,采用的版本3.2.2,可支持多种插件,此次实现可拖动时间轴的功能也是使用了它的一款插件, 该插件名为:flowplayer.pseudostreaming-byterange-3.2.9.swf,采用的版本是3.2.9,3.2.10不可作为flowPlayer3.2.2的插件使用, 测试未有图像显示。页面中的编写方式是,红色标出的是重要部分:

<%@ page language=“Java” import=“java.util.*;” pageEncoding=“UTF-8″%>

<%@ taglib prefix=“c” uri=“http://java.sun.com/jstl/core”%>

<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”>

<html>

    <head>

       <title>FLV</title>

       <script type=”text/JavaScript

           src=”<c:url value=“/script/jQuery-1.5.2.min.js” />”></script>

       <script type=“text/javascript

           src=”<c:url value=“/_flowplayer/flowplayer-3.2.4.min.js”/>”></script>

 

    </head>

    <body>

 

       <script type=“text/javascript”>

       <!–

           var p;

           $(function(){

              p = $(“.player”).flowplayer(

                  {

                     src:’<c:url value=”/_flowplayer/flowplayer.commercial.swf”/>’,

                     wmode: “opaque”

                  },

                  {

                     clip:{

                         //scaling: ‘orig’,   设置播放器读取原始视频高宽比

                         autoPlay: true,

                         autoBuffering: true,

                         bufferLength: 1,

                         provider: ‘lighttpd’

                  },

                  plugins: {

                     controls: {

                         url: ‘<c:url value=”/_flowplayer/flowplayer.controls-air-3.2.2.swf”/>’,

                         opacity: 0.8,

                         backgroundColor: ‘#000′,

                         scrubber : true,

                        

                         buttonColor: ‘#000′,

                         buttonOverColor: ‘#4c4c4c’,

                        

                         autoHide: {

                            enabled: true,

                            fullscreenOnly: false,

                            hideDelay: 1000,

                            mouseOutDelay: 2000,

                            hideStyle: ‘fade’

                         }  

                     },

                     lighttpd: {

                          url: “<c:url value=”/_flowplayer/flowplayer.pseudostreaming-byterange-3.2.9.swf”/>”

                         ,queryString: escape(‘?target=${“${start}”}&secretToken=1235oh8qewr5uweynkc’)

                            // queryString配置了拖动时间轴后发送到后台的参数。${start}为固定格式。

                      }                                                

                  },

                  play: { replayLabel : “再次播放”, width:120 , height: 50}

              })

           })

       //à

       </script>

       <!—视频展示区域à

       <div class=”left_video_areaBg clearWrap”>

           <!—视频限制高宽 W:451px H:252pxà

           <a class=”player”

              href=”<c:url value=”/movie/131201174437530567C.flv”/>”

              style=”display: block; width: 429px; height: 252px;” id=”player1”>

           </a>

       </div>

        <div class=”left_video_dotLine”></div>

       <div class=”blank8”></div>

 

       <button onclick=”$f().seek(60);”>1分钟</button>

       <button onclick=”$f().seek(180);”>3分钟</button>

       <button onclick=”alert($f().getTime());”>获取当前时间点</button>

    </body>

</html>

三、实现流式输出的Servlet的编写

package flv.laukin.NET;

 

import java.io.IOException;

import java.io.RandomAccessFile;

 

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

public class FlvStreamServlet extends HttpServlet{

 

    protected void doGet(HttpServletRequest req, HttpServletResponse resp)

            throws ServletException, IOException {

        // TODO Auto-generated method stub

       

        resp.reset();

        resp.setContentType(“Video/x-flv”);

       

        String target = req.getParameter(“target”);  //接收参数,为字节数

        int targetInt = 0;

 

        System.out.println(“Target:” + target);

        System.out.println(“Target:” + req.getServletPath());

        String flvPath = req.getSession().getServletContext().getRealPath(req.getServletPath());

        System.out.println(flvPath);

       

        RandomAccessFile raf = null;

        int totalByte = 0;

        try{

            raf = new RandomAccessFile(flvPath, “r”);

            totalByte = (int)raf.length();

           

            if (target != null && !”".equals(target)) {

                try {

                    targetInt = Integer.parseInt(target);

            byte[] headData = new byte[]{‘F’,'L’,'V’,1,1,0,0,0,9,0,0,0,9}; //拖动时间轴后的response中头信息需写入该字节 

                    resp.getOutputStream().write(headData);

                    resp.setContentLength(totalByte – targetInt + 13);

                } catch (NumberFormatException e) {

                    targetInt = 0;

                }

            } else {

                resp.setContentLength(totalByte – targetInt);

            }

           

            raf.skipBytes(targetInt);//跳过时间轴前面的字节;

           

            byte[] b = new byte[4096];

            while(raf.read(b) != -1) {

                resp.getOutputStream().write(b);

            }

            resp.getOutputStream().flush();

           

        } catch (Exception e) {

            String simplename = e.getClass().getSimpleName();

            if(!”ClientAbortException”.equals(simplename)){

                e.printStackTrace();

            }//web端拖动时间轴总有连接被重置的异常,暂时还不知如何解决,可以此方式不输出异常

        } finally {

            if(raf != null){

                raf.close();

            }

        }

    }

}

web.xml中增加配置:

    <servlet>

       <servlet-name>FlvStream</servlet-name>

       <servlet-class>flv.laukin.net.FlvStreamServlet</servlet-class>

       <load-on-startup>1</load-on-startup>

    </servlet>

    <servlet-mapping>

       <servlet-name>FlvStream</servlet-name>

       <url-pattern>*.flv</url-pattern>

</servlet-mapping>

至此Tomcat下的FLV播放就可实现任意拖动了。

下面的连接为项目代码,可下载交流,测试可自己制作 flv 放到 movie目录下。

FLVstreaming

 

来源:http://www.laukin.net/wordpress/archives/191

时间: 2024-12-28 10:20:37

HTTP协议下可拖动时间轴播放FLV的实现(伪流媒体)的相关文章

《Adobe Flash CS5 ActionScript 3.0中文版经典教程》——1.4 在Flash时间轴上放置代码

1.4 在Flash时间轴上放置代码 1.4.1 使用帧标签 在开始添加ActionScript之前,注意在时间轴上有一个图层称为"说明"(Label).在这个图层中,第2帧有一个标签,称为loop,第50帧有一个标签,称为home.在Flash中可以向任意时间轴上的任意关键帧添加标签,用来标记一些关键的位置.ActionScript可以使用标签来控制导航.如果以前没有使用过标签,可以实践一下,在第30帧上给时间轴添加一个标签. 1.选择时间轴上标签图层中的第30帧. 2.按F6键或选

TimergliderJS 一个基于jQuery的时间轴插件_jquery

Timeglider JS是一个由javascript支持缩放,数据驱动的时间轴组件.非常适合显示项目历史,项目计划及其其它需要显示历史的项目. 时间轴可以通过右边拖放垂直滑动器来缩放界面:向上缩小,向下放大.同时也支持使用滚轮来控制缩放.通过鼠标拖东空白处可以左右拖动时间轴,点击事件可以弹出一个小窗口来描述时间内容及其数据. JS组件有以下几个目标: 支持iPads和其它支持触摸的设备 非常容易整合到基于HTML/JS应用和界面 支持复杂的布局,并且可以对任何指定自定义HTML元素添加事件 安

分享一个jQuery的时间轴插件:TimergliderJS

在线演示1  在线演示2 Timeglider JS是一个由javascript支持缩放,数据驱动的时间轴组件.非常适合显示项目历史,项目计划及其其它需要显示历史的项目. 时间轴可以通过右边拖放垂直滑动器来缩放界面:向上缩小,向下放大.同时也支持使用滚轮来控制缩放.通过鼠标拖东空白处可以左右拖动时间轴,点击事件可以弹出一个小窗口来描述时间内容及其数据. JS组件有以下几个目标: 支持iPads和其它支持触摸的设备 非常容易整合到基于HTML/JS应用和界面 支持复杂的布局,并且可以对任何指定自定

Flash MX 2004时间轴特效详细讲解

特效 今天给大家总结一下Flash mx 2004中的时间轴特效,希望对大家有帮助,并且提供了一个用时间轴做的实例,至于其它的具体简单使用则没给大家实例,希望大家按照说得好好练习下Flash的时间轴特效! 时间轴特效(Timeline effects)是Flash MX 2004和Flash MX Professional 2004都拥有的新功能.使用Flash内建的时间轴特效,可以快速创建复杂的动画,和Swish有些类似. 时间轴特效可以应用于以下对象:文本.图形(包括矢量图.组合对象和图符)

使用css3伪元素制作时间轴并且实现鼠标选中高亮效果

利用css3来制作时间轴的知识要点:伪元素,以及如何在伪元素上添加锚伪类 1)::before 在元素之前添加内容. 2)::after 在元素之后添加内容. 提示:亦可写成 :before :after CSS3将伪对象选择符前面的单个冒号(:)修改为双冒号(::)用以区别伪类选择符,但以前的写法仍然有效. 预览地址:http://www.yangqq.com/web/time.html 代码分析:右边那条黑色竖线,可以看成是右边框.也可以用伪元素after或者before实现,所以方法有很多

java制作的MP3播放器,如何实现时间轴功能

问题描述 我使用的是javax.sound.sampled.SourceDataLine+MP3spi用来播放.求解如何实现时间轴的功能.使用javax.sound.sampled.Clip也试过,虽然有时间轴功能,但是加载音乐时间过长(大概5秒),内存占用过大.求各位大神好的解决方法. 解决方案 解决方案二:来大神啊!!!!!!!!!!!!顶解决方案三:Slider参考

《Adobe Flash CS5中文版经典教程》——1.4 了解“时间轴”

1.4 了解"时间轴" "时间轴"位于"舞台"下面.像电影一样,Flash文档以帧为单位度量时间.在影片播放时,播放头(如红色垂直线所示)在"时间轴"中向前移过帧.可以为不同的帧更改"舞台"上的内容.要在"舞台"上显示帧的内容,可以在"时间轴"中把播放头移到那个帧上. 在"时间轴"的底部,Flash会指示所选的帧编号.当前帧频(每秒钟播放多少帧),

《Adobe Flash CS4中文版经典教程》——1.4 了解“时间轴”

1.4 了解"时间轴" "时间轴"位于"舞台"下面.像电影一样,Flash文档以帧为单位度量时间.在播放影片时,播放头(如红色垂直线所示)在"时间轴"中向前移过帧.用户可以为不同的帧更改"舞台"上的内容.要在"舞台"上显示帧的内容,可以在"时间轴"中把播放头移到那个帧上. 在"时间轴"的底部,Flash会指示所选的帧编号.当前帧速率(每秒钟播放多少

《Adobe Flash Professional CC经典教程》——1.4 了解“时间轴”

1.4 了解"时间轴" "时间轴"位于"舞台"下方.像电影一样,Flash文档以帧为单位度量时间.在影片播放时,播放头(如红色垂直线所示)在"时间轴"中向前移动.可以为不同的帧更改"舞台"上的内容.要在"舞台"上显示帧的内容,可以在"时间轴"中把播放头移到比帧上. 在"时间轴"的底部,Flash会指示所选的帧编号.当前帧频(每秒钟播放多少帧),以及