停止用户从服务器下载文件 - JWPlayer + Coldfusion

问题描述:

我有一个应用程序,我使用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响应,然后开始播放视频。 –

要阻止用户下载结果视频,而不是将视频直接嵌入到源视频中,您可以通过RTMP或HLS/MPEG-Dash以流播放视频。

这里是一个demo for webcam video recorder,还包括RTMP播放(既可以在录音机中预览,也可以根据请求提供)。

录制应用程序和播放器是基于浏览器的,您通常可以根据自己选择的语言来调整服务器端脚本。