我有一个asp.net webforms应用程序,可以从以varbinary
格式保存的数据库中检索视频,并将其显示为html5视频标记。
ASP.Net WebApi
异步播放它,它工作正常
第一个问题
当视频第一次播放并且用户点击播放按钮重播视频时,The remote host closed the connection. The error code is 0x800704CD
异常将在await outputStream.WriteAsync(buffer, 0, bytesRead);
行投放。
第二个问题
当用户点击搜索栏时,视频将从第一个开始播放。
注意
Internet Explorer 11 播放视频没有任何问题,但firefox和chrome都有问题。
我该如何解决这个问题?
这是我的代码:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.EnableCors();
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "VideoApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
public class VideoController : ApiController
{
public IVideoRepository videoRepository;
public HttpResponseMessage Get(long id)
{
try
{
videoRepository = new VideoRepository();
Video video = videoRepository.load(id);
if (video != null)
{
var videoStream = new VideoStream(video.fileContent);
string ext = video.extension;
var response = Request.CreateResponse();
response.Content = new PushStreamContent((Action<Stream, HttpContent, TransportContext>)videoStream.WriteToStream, new MediaTypeHeaderValue("video/" + ext));
response.Content.Headers.Add("Content-Disposition", "attachment;filename=" + video.fullName.Replace(" ", ""));
response.Content.Headers.Add("Content-Length", videoStream.FileLength.ToString());
return response;
}
else
{
return Request.CreateResponse(HttpStatusCode.NotFound);
}
}
catch (Exception e)
{
return Request.CreateErrorResponse(HttpStatusCode.ServiceUnavailable, e);
}
}
}
public class VideoStream
{
private readonly byte[] _fileContent;
private long _contentLength;
public long FileLength
{
get { return _contentLength; }
}
public VideoStream(byte[] content)
{
_contentLength = content.Length;
_fileContent = content;
}
public async void WriteToStream(Stream outputStream, HttpContent content, TransportContext context)
{
try
{
var buffer = new byte[65536];
MemoryStream memoryStream = new MemoryStream();
memoryStream.Write(_fileContent, 0, _fileContent.Length);
memoryStream.Position = 0;
using (memoryStream)
{
var length = (int)memoryStream.Length;
var bytesRead = 1;
while (length > 0 && bytesRead > 0)
{
bytesRead = memoryStream.Read(buffer, 0, Math.Min(length, buffer.Length));
await outputStream.WriteAsync(buffer, 0, bytesRead);
length -= bytesRead;
}
}
}
catch (Exception e)
{
throw e;
}
finally
{
outputStream.Close();
}
}
}
更新
在这种方式不能正常工作之后,我不得不使用this way,但是当新用户点击搜索栏以寻找时间时,新方式会出现搜索栏问题,这在Chrome和FireFox中无效。
答案 0 :(得分:0)
ASP.NET不擅长视频流。第三方视频流解决方案是最佳选择。
有一些视频流服务器(如Wowza),但它们需要安装,您必须购买许可证。
云端流服务是另一种选择。我个人更喜欢AWS Cloudfront。他们建议在各种全球分布的内容交付区域中分发。它的成本非常便宜,您可以确定它可以在任何流量下存活(即使您的所有用户同时观看同一视频)。
答案 1 :(得分:0)
现在你可能已经知道答案了。但这可能会帮助其他人-
我最好的办法是从响应标头中删除 Content-length
。
Content-Length
告诉调用者它需要在响应中接收这个固定长度。
当您点击播放按钮时,没有收到完整的视频流(即没有收到整个 Content-Length。)因此,错误。
另一种方法可能是使用 response.Headers.TransferEncodingChunked = true
,它告诉调用者它将以块的形式接收响应。这里唯一的问题是,即使流不存在,您也会得到 200OK。