Я пытаюсь создать очень простую html5-страницу, которая загружает видео .mp4 размером 20 МБ. Кажется, что браузеру нужно загрузить все видео, а не просто воспроизвести первую часть видео и передать остальное.
Этот пост - самое близкое, что я нашел в процессе поиска... Я пробовал и Hand Brake, и Data Go Round, но ни то, ни другое не помогло:
Есть идеи, как это сделать или возможно ли это?
Вот код, который я использую:
<video controls="controls">
<source src="/video.mp4" type="video/mp4" />
Your browser does not support the video tag.
</video>
moov
(метаданные) находится перед mdat
(аудио/видео данные). Это также называется "быстрый старт" или "веб-оптимизация". Например, Handbrake имеет флажок "Web Optimized", а ffmpeg и avconv имеют опцию вывода -movflags faststart
.Вы можете проверить заголовки, отправляемые вашим веб-сервером, используя curl -I http://yoursite/video.mp4
или используя инструменты разработчика в вашем браузере (Chrome, Firefox) (перезагрузите страницу, если она кэширована). Заголовок HTTP-ответа должен включать Content-Type: video/mp4 и Accept-Ranges: bytes, и не содержать Content-Encoding:.
Вот решение, которое я использовал для создания контроллера Web API на C# (MVC), который будет обслуживать видеофайлы с диапазонами байтов (частичные запросы). Частичные запросы позволяют браузеру загружать только ту часть видео, которая необходима для воспроизведения, а не загружать видео целиком. Это делает его гораздо более эффективным.
Обратите внимание, что это работает только в последних версиях.
var stream = new FileStream(videoFilename, FileMode.Open, FileAccess.Read , FileShare.Read);
var mediaType = MediaTypeHeaderValue.Parse($"video/{videoFormat}");
if (Request.Headers.Range != null)
{
try
{
var partialResponse = Request.CreateResponse(HttpStatusCode.PartialContent);
partialResponse.Content = new ByteRangeStreamContent(stream, Request.Headers.Range, mediaType);
return partialResponse;
}
catch (InvalidByteRangeException invalidByteRangeException)
{
return Request.CreateErrorResponse(invalidByteRangeException);
}
}
else
{
// If it is not a range request we just send the whole thing as normal
var fullResponse = Request.CreateResponse(HttpStatusCode.OK);
fullResponse.Content = new StreamContent(stream);
fullResponse.Content.Headers.ContentType = mediaType;
return fullResponse;
}