HTTP協議下可拖動時間軸播放FLV的實現(偽流媒體)

來源:互聯網
上載者:User

標籤:推薦   tac   fms   read   rdp   tomcat   ons   orm   val   

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

HTTP協議下可拖動時間軸播放FLV的實現(偽流媒體)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.