2017-05-26 45 views
1

我有一個應用程序,我使用wowza服務器和hdfvr進行視頻錄製。我使用jwplayer在網站上播放視頻。停止用戶從服務器下載文件 - JWPlayer + Coldfusion

我需要知道如何停止用戶下載mp4文件。目前我正在使用認證後返回媒體流的Coldfusion。這是返回mp4內容的文件代碼部分。

<cfif FileExists(videoPath)> 
         <cfset fileInfoVar = GetFileInfo(videoPath)> 
         <cfheader name="Last-Modified" value="#fileInfoVar.Lastmodified#"> 
         <cfheader name="ETag" value="#hash(videoPath, 'MD5')#"> 
         <cfheader name="Content-Location" value="https://example.com/videoreturnfile.cfm"> 

         <cfif structKeyExists(GetHttpRequestData().headers, 'Range')> 
          <cfset rangeDownload(videoPath)> 
         <cfelse> 
          <cffile action="readbinary" file="#videoPath#" variable="theData"> 
          <cfscript> 
           context = getPageContext(); 
           context.setFlushOutput(false); 
           response = context.getResponse().getResponse(); 
           response.setContentType("video/mp4"); 
           response.setContentLength(arrayLen(theData)); 

           out = response.getOutputStream(); 
           out.write(theData); 
           out.flush(); 
           out.close(); 
          </cfscript> 
         </cfif> 
        </cfif> 
<cffunction name="rangeDownload" returnType="void" output="yes"> 
    <cfargument name="file" type="string" required="true" hint="path to file"> 

    <cfset var l = {}> 
    <cfset l.request = GetHttpRequestData()> 

    <cffile action="readbinary" file="#ARGUMENTS.file#" variable="l.theData"> 

    <cfset l.size = arrayLen(l.theData)> 
    <cfset l.length = l.size> 
    <cfset l.start = 0> 
    <cfset l.end = l.size - 1> 

    <!--- Now that we've gotten so far without errors we send the accept range header 
    /* At the moment we only support single ranges. 
    * Multiple ranges requires some more work to ensure it works correctly 
    * and comply with the spesifications: http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.2 
    * 
    * Multirange support annouces itself with: 
    * header('Accept-Ranges: bytes'); 
    * 
    * Multirange content must be sent with multipart/byteranges mediatype, 
    * (mediatype = mimetype) 
    * as well as a boundry header to indicate the various chunks of data. 
    */ 
    ---> 
    <cfheader name="Accept-Ranges" value="0-#l.length#"> 
    <!---<cfheader name="Accept-Ranges" value="bytes"> ---> 
    <!--- 
     multipart/byteranges 
     http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.2 ---> 
    <cfif structKeyExists(l.request.headers, 'Range')> 

     <cfset l.c_start = l.start> 
     <cfset l.c_end = l.end> 

     <!--- Extract the range string ---> 
     <cfset l.range = ListGetAt(l.request.headers.range, 2, '=')> 
     <!--- Make sure the client hasn't sent us a multibyte range ---> 
     <cflog file="rangeDownload" text="#l.range#" /> 
     <cfif l.range contains ','> 
      <!--- (?) Should this be issued here, or should the first 
      range be used? Or should the header be ignored and 
      we output the whole content? 
      ---> 
      <cfheader statusCode = "416" statusText = "Requested Range Not Satisfiable"> 
      <cfheader name="Content-Range" value="bytes #l.start#-#l.end#/#l.size#"> 
      <!--- (?) Echo some info to the client? ---> 
      <cfabort> 
     </cfif> 
     <!--- If the range starts with an '-' we start from the beginning 
      If not, we forward the file pointer 
      And make sure to get the end byte if specified ---> 
     <cfif Left(l.range, 1) eq '-'> 
     <!--- The n-number of the last bytes is requested ---> 
      <cfset l.c_start = l.size - Mid(l.range, 2, Len(l.range))> 
     <cfelse> 
      <cfset l.rangeArray = ListToArray(l.range, '-')> 
      <cfset l.c_start = l.rangeArray[1]> 
      <cfif ArrayLen(l.rangeArray) eq 2 and val(l.rangeArray[2]) gt 0> 
       <cfset l.c_end = l.rangeArray[2]> 
      <cfelse> 
       <cfset l.c_end = l.size> 
      </cfif> 
     </cfif> 
     <!--- 
     /* Check the range and make sure it's treated according to the specs. 
     * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html 
     */ 
     // End bytes can not be larger than l.end. ---> 
     <cfif l.c_end gt l.end> 
      <cfset l.c_end = l.end> 
     </cfif> 

     <!--- Validate the requested range and return an error if it's not correct. ---> 
     <cfif l.c_start gt l.c_end || l.c_start gt (l.size - 1) || l.c_end gte l.size> 
      <cfheader statusCode = "416" statusText = "Requested Range Not Satisfiable"> 
      <cfheader name="Content-Range" value="bytes #l.start#-#l.end#/#l.size#"> 
      <!--- (?) Echo some info to the client? ---> 
      <cfabort> 
     </cfif> 

     <cfset l.start = l.c_start> 
     <cfset l.end = l.c_end> 
     <cfset l.length = l.end - l.start + 1><!--- Calculate new content length ---> 


     <cfscript> 
      context = getPageContext(); 
      context.setFlushOutput(false); 
      response = context.getResponse().getResponse(); 
      response.setContentType("video/mp4"); 
      response.setContentLength(l.length); 
     </cfscript> 
     <cfheader statusCode = "206" statusText = "Partial Content"> 

    </cfif> 

    <!--- Notify the client the byte range we'll be outputting ---> 
    <cfheader name="Content-Range" value="bytes #l.start#-#l.end#/#l.size#"> 
    <cfheader name="Content-Length" value="#l.length#"> 

    <cfscript> 
     // Start buffered download 
     out = response.getOutputStream(); 
     // write the portion requested 
     out.write(l.theData, javacast('int', l.start), javacast('int', l.length)); 
     out.flush(); 
     out.close(); 
    </cfscript> 
</cffunction> 

這是我用來播放視頻的JWplayer代碼。

jwplayer("myElement4859").setup({ 
            image: "path to image file", 
            file: "/videoreturnfile.cfm?token=4859_129_AC4E46D8-5056-A85D-6EDDE334152C27EE", 
            height: 360, 
            logo: { 
             file: '/images/logo_message.png', 
             link: 'example.com', 
             hide : true 
            }, 
            width: 450, 
            type: "mp4" 
           }); 

jwplayer有什麼辦法可以通過它來限制我的視頻應該和我的jwplayer插件一起玩嗎?

或者有什麼建議可以讓用戶下載文件變得更加複雜?

+1

你能看看jwplayer的請求,並確定它是否添加了任何特殊的頭文件?如果是這樣,你可以基於此進行過濾。您可以使用此方法支持多少個同步流。我猜不是很多。如果任何視頻開始有點病毒,所有CFThreads都會忙/等待。如果頭部參數丟失,您可以使用條件URL重寫規則重新路由到403/404頁面(並將ColdFusion從此瓶頸解決方案中取出。) –

+1

我們使用ColdFusion(自CF3以來),並且最近從未受保護的媒體音頻流切換到使用StreamGuys.com。他們允許我們通過訂閱獲利,保護,過期和限制爲單個用戶。我們生成一個加密的標記(包含用戶標識,窗口和超時)並重定向到他們的媒體服務器。我們編寫的基於HTML的ColdFusion應用程序比第三方開發人員創建的iOS/Android本機應用程序要好得多。 –

+0

@JamesMoberg。我擔心jwplayer不支持任何特殊的標題。使用這種方法的主要目的是在IOS上運行視頻。 IOS確實需要url響應,然後開始播放視頻。 –

回答

0

要阻止用戶下載結果視頻,而不是將視頻直接嵌入到源視頻中,您可以通過RTMP或HLS/MPEG-Dash以流播放視頻。

這裏是一個demo for webcam video recorder,還包括RTMP播放(既可以在錄音機中預覽,也可以根據請求提供)。

錄製應用程序和播放器是基於瀏覽器的,您通常可以根據自己選擇的語言來調整服務器端腳本。