Я пытаюсь использовать обработчик ashx в качестве источника видео HTML5. Я могу этого добиться, но не могу двигаться дальше по видео, которое уже буферизовано.
Я могу видеть на вкладке сети, используя стандартный источник MP4, который при поиске вперед создает другой запрос, но с использованием обработчика этого не происходит.
Некоторые видео имеют размер более 1 ГБ.
Вот что мне нужно, чтобы видео работали до сих пор:
public void ProcessRequest(HttpContext context)
{
context.Response.Buffer = false;
context.Response.ContentType = "video/mp4";
FileInfo file = new FileInfo(path);
int len = (int)file.Length, bytes;
context.Response.AppendHeader("content-length", len.ToString());
byte[] buffer = new byte[1024];
Stream outStream = context.Response.OutputStream;
using (Stream stream = File.OpenRead(path))
{
while (len > 0 && (bytes = stream.Read(buffer, 0, buffer.Length)) > 0)
{
outStream.Write(buffer, 0, bytes);
len -= bytes;
}
}
}
Взято из сообщения Марка Гравелла Лучший способ потоковой передачи файлов в ASP. NET:
<video id="video-player" class="video-js vjs-default-skin" controls
preload="auto" poster="MY_VIDEO_POSTER.jpg"
data-setup="{}">
<source src="/Handlers/VideoHandler.ashx" type='video/mp4'>
<p class="vjs-no-js">
To view this video please enable JavaScript, and consider upgrading to a web browser that
<a href="http://videojs.com/html5-video-support/" target="_blank">supports HTML5 video</a>
</p>
</video>
используя video.js, но то же самое происходит, если я вызываю обработчик прямо в браузере.
Как я могу исправить эту проблему? Скорее всего, я упустил что-то простое.
ОБНОВЛЕНИЕ
Посмотрев дальше, я теперь знаю, что мне нужны «диапазоны приема».
У меня теперь есть
context.Response.ContentType = "video/mp4";
var request = HttpContext.Current.Request;
FileInfo file = new FileInfo(filePath);
var responseLength = (int)file.Length;
var buffer = new byte[1024];
var startIndex = 0;
if (request.Headers["Range"] != null)
{
var match = Regex.Match(request.Headers["Range"], @"bytes=(\d*)-(\d*)");
startIndex = Parse<int>(match.Groups[1].Value);
responseLength = (Parse<int?>(match.Groups[2].Value) + 1 ?? responseLength) - startIndex;
context.Response.StatusCode = (int)HttpStatusCode.PartialContent;
context.Response.Headers["Content-Range"] = "bytes " + startIndex + "-" + (startIndex + responseLength - 1) + "/" + responseLength;
}
context.Response.Headers["Accept-Ranges"] = "bytes";
context.Response.Headers["Content-Length"] = responseLength.ToString();
context.Response.Cache.SetCacheability(HttpCacheability.Public);
context.Response.Buffer = false;
с помощью Поддерживая возобновляемые загрузки HTTP через обработчик ASHX?, но теперь запись вызывает у меня проблемы с ошибкой
HttpException не было обработано пользовательским кодом. Удаленный хост закрыл соединение. Код ошибки - 0x800704CD.
Я пытался:
using (Stream stream = File.OpenRead(filePath))
{
stream.Seek(startIndex, SeekOrigin.Begin);
while ((responseLength - startIndex) > 0 && (bytes = stream.Read(buffer, 0, buffer.Length)) > 0)
{
response.OutputStream.Write(buffer, 0, bytes);
responseLength -= bytes;
}
}
а также
using (Stream stream = File.OpenRead(filePath))
{
stream.Seek(startIndex, SeekOrigin.Begin);
int bufferLength = buffer.Length, bytesRead;
while (responseLength > bufferLength && (bytesRead = stream.Read(buffer, 0, bufferLength)) > 0)
{
response.OutputStream.Write(buffer, 0, bytesRead);
responseLength -= bytesRead;
}
while (responseLength > 0 && (bytesRead = stream.Read(buffer, 0, responseLength)) > 0)
{
response.OutputStream.Write(buffer, 0, bytesRead);
responseLength -= bytesRead;
}
}
Как я могу исправить эту проблему?