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插件一起玩嗎?
或者有什麼建議可以讓用戶下載文件變得更加複雜?
你能看看jwplayer的請求,並確定它是否添加了任何特殊的頭文件?如果是這樣,你可以基於此進行過濾。您可以使用此方法支持多少個同步流。我猜不是很多。如果任何視頻開始有點病毒,所有CFThreads都會忙/等待。如果頭部參數丟失,您可以使用條件URL重寫規則重新路由到403/404頁面(並將ColdFusion從此瓶頸解決方案中取出。) –
我們使用ColdFusion(自CF3以來),並且最近從未受保護的媒體音頻流切換到使用StreamGuys.com。他們允許我們通過訂閱獲利,保護,過期和限制爲單個用戶。我們生成一個加密的標記(包含用戶標識,窗口和超時)並重定向到他們的媒體服務器。我們編寫的基於HTML的ColdFusion應用程序比第三方開發人員創建的iOS/Android本機應用程序要好得多。 –
@JamesMoberg。我擔心jwplayer不支持任何特殊的標題。使用這種方法的主要目的是在IOS上運行視頻。 IOS確實需要url響應,然後開始播放視頻。 –