首页 新闻 会员 周边

mp4文件播放和下载控制

0
悬赏园豆:50 [已解决问题] 解决于 2016-06-06 15:33

项目需要对mp4文件做权限控制。不能让用户在浏览器输入mp4文件目录就直接下载或者播放。

我的做法是给mp4文件做了handler,在handler里做权限控制。

现在的问题是,文件下载没有问题,但是不能播放。大家看看问题出在哪里???

handler代码如下:

 1 public void ProcessRequest(HttpContext context)
 2         {
 3             Request = context.Request;
 4             Response = context.Response;
 5             //write your handler implementation here.
 6            
 7             Stream iStream = null;
 8             // Buffer to read 10K bytes in chunk:
 9             byte[] buffer = new Byte[10000];
10             // Length of the file:
11             int length;
12             // Total bytes to read:
13             long dataToRead;
14             // Identify the file to download including its path.
15             string filepath = context.Request.PhysicalPath;
16             // Identify the file name.
17             string filename = System.IO.Path.GetFileName(filepath);
18             try
19             {
20 
21                 // Open the file.
22                 iStream = new System.IO.FileStream(filepath, System.IO.FileMode.Open,
23                 System.IO.FileAccess.Read, System.IO.FileShare.Read);
24                 // Total bytes to read:
25                 dataToRead = iStream.Length;
26                 Response.ContentType = "video/mp4";
27                 //Response.AddHeader("Content-Disposition", "attachment; filename=" + filename);
28                 // Read the bytes.
29                 while (dataToRead > 0)
30                 {
31                     // Verify that the client is connected.
32                     if (Response.IsClientConnected)
33                     {
34                         // Read the data in buffer.
35                         length = iStream.Read(buffer, 0, 10000);
36                         // Write the data to the current output stream.
37                         Response.OutputStream.Write(buffer, 0, length);
38                         // Flush the data to the HTML output.
39                         Response.Flush();
40                         buffer = new Byte[10000];
41                         dataToRead = dataToRead - length;
42                     }
43                     else
44                     {
45                         //prevent infinite loop if user disconnects
46                         dataToRead = -1;
47                     }
48 
49                 }
50 
51             }
52             catch (Exception ex)
53             {
54                 // Trap the error, if any.
55                 Response.Write("Error : " + ex.Message);
56             }
57             finally
58             {
59 
60                 if (iStream != null)
61                 {
62                     //Close the file.
63                     iStream.Close();
64                 }
65             }
66         }
OOLi的主页 OOLi | 初学一级 | 园豆:163
提问于:2013-09-29 10:44
< >
分享
最佳答案
0

http://gnehcic.azurewebsites.net/%E5%AF%A6%E4%BD%9Cmp4%E5%88%86%E6%AE%B5%E4%B8%8B%E8%BC%89/

建议参考下这个。视频播放,Http请求的Header中含有Range属性,需要处理一下。下边是一个实现,可以下载,可以播放。

var Request = context.Request;
var Response = context.Response;

Response.CacheControl = "public";

var fileName = Request.QueryString["filename"];
if (!string.IsNullOrWhiteSpace(fileName))
{
FileStream stm = null;
try
{
FileInfo fi = new FileInfo(Path.Combine(Global.ServerPath, fileName));

stm = new FileStream(fi.FullName, FileMode.Open, FileAccess.Read);

///处理HttpHeaders,HttpHeaderVariable是自定义的一个类,见最后。
var vary = HttpHeaderVariable.Init(Request);

vary.Range.Total = fi.Length;
if (vary.Range.End == 0 || vary.Range.End > vary.Range.Total - 1)
{
vary.Range.End = vary.Range.Total - 1;
}

if (vary.IsContainsModify)
{
if (fi.LastWriteTimeUtc <= vary.SinceModify)
{
Response.StatusCode = 304;
Response.Headers.Add("Etag", GetEtag(fi));
Response.End();
}
}
if (vary.IsContanisIfRange)
{
if (GetEtag(fi) == vary.IfRangeString)
{
Response.StatusCode = 206;
Response.Headers.Add("Etag", GetEtag(fi));
}//get all
else
{
vary.Range.Start = 0;
vary.Range.End = vary.Range.Total - 1;
}
}

if (vary.IsContainsRange) Response.StatusCode = 206;
else Response.StatusCode = 200;

Response.AddHeader("Accept-Ranges", "bytes");
Response.AddHeader("Connection", "keep-alive");
Response.AddHeader("Content-Length", vary.Range.Length.ToString());
Response.AddHeader("Content-Range", string.Format("bytes {0}-{1}/{2}", vary.Range.Start, vary.Range.End, vary.Range.Total));
Response.ContentType = "video/mp4";


Response.Cache.SetMaxAge(TimeSpan.FromHours(1));
Response.Cache.SetETag(GetEtag(fi));
Response.Cache.SetExpires(DateTime.Now.AddDays(3));
Response.Cache.SetLastModified(fi.LastWriteTime);

stm.Position = vary.Range.Start;
long totalLength = vary.Range.Length;
var buffer = new byte[1024];
int n = 1;
while (totalLength > 0 && n > 0)
{
n = stm.Read(buffer, 0, (int)Math.Min(totalLength, buffer.Length));
Response.OutputStream.Write(buffer, 0, n);
totalLength -= n;
}
}
finally
{
if (stm != null)
{
stm.Dispose();
}
Response.End();
}
}
}

private string GetEtag(FileInfo fi)
{
//return Meng.Web.Common.Utility.GetSHA256String(fi.FullName + fi.LastWriteTime);
return fi.FullName;
}

 

public class HttpHeaderVariable
{
public bool IsContainsRange { get; set; }
public ContentRange Range { get; set; }

public bool IsContainsModify { get; set; }
public DateTime SinceModify { get; set; }

public bool IsContanisIfRange { get; set; }
public string IfRangeString { get; set; }

public bool IsContainsUnmodified { get; set; }

public DateTime SinceUnmodify { get; set; }

public static HttpHeaderVariable Init(HttpRequest request)
{
HttpHeaderVariable r = new HttpHeaderVariable();
r.Range = new ContentRange();

var ifRanges = request.Headers.GetValues("If-Range");
if (ifRanges != null)
{
r.IsContanisIfRange = true;
r.IfRangeString = ifRanges[0];
}
var ifModifies = request.Headers.GetValues("If-Modified-Since");
if (ifModifies != null)
{
r.IsContainsModify = true;
r.SinceModify = Convert.ToDateTime(ifModifies[0]);
}

var ifUnmodifies = request.Headers.GetValues("If-Unmodified-Since");
if (ifUnmodifies != null)
{
r.IsContainsUnmodified = true;
r.SinceUnmodify = Convert.ToDateTime(ifUnmodifies[0]);
}

var ranges = request.Headers.GetValues("Range");
if (ranges != null)
{
r.IsContainsRange = true;

var range = ranges[0];
int indexD = range.IndexOf('=');
int indexJ = range.IndexOf('-');

r.Range.Start = Convert.ToInt32(range.Substring(indexD + 1, indexJ - indexD - 1));

if (indexJ == range.Length - 1)
r.Range.End = 0;
else
r.Range.End = Convert.ToInt32(range.Substring(indexJ + 1, range.Length - indexJ - 1));
}
return r;
}

public class ContentRange
{
public long Start { get; set; }
public long End { get; set; }
public long Total { get; set; }
public long Length { get { return End - Start + 1; } }
public ContentRange(long start, long end, long total)
{
Start = start;
End = end;
Total = total;
}
public ContentRange()
{

}
}

收获园豆:50
Simonn | 菜鸟二级 |园豆:254 | 2015-01-09 14:05
其他回答(3)
0

 建议楼主检查一下,文件是否一致。

sinhbv | 园豆:2579 (老鸟四级) | 2013-09-29 12:24
0

是不是没有设置文件类型stream什么的

angelshelter | 园豆:9887 (大侠五级) | 2013-09-29 15:36
0

可能的原因是 网页播放器请求视频时 无法正常获取视频

未附带cookies或者其他

WILL WIN | 园豆:104 (初学一级) | 2013-10-17 15:20
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册