Проблема с видео и аудио html5

Я написал специальный предварительный ng2 app мультимедиа, который использует серию XMLHttpRequests для загрузки большого количества носителей перед отображением моего ng2 app . Требование заинтересованных сторон состоит в том, чтобы все носители загружались полностью до использования приложения.

  private loadFile(media: any) { return new Promise(function (resolve, reject) { var error: boolean = false; //for (var media of media.videos) { //TODO: Check how this loads..... //console.log("Now Loading video >> ", media, media.hasOwnProperty("path")); // Standard XHR to load an image var request = new XMLHttpRequest(); request.open("GET", (media).path); request.responseType = 'blob'; // When the request loads, check whether it was successful request.onload = () => { if (request.status === 200) { resolve(request.response); } else // If it fails, reject the promise with a error message reject(Error('Media didn\'t load successfully; error code:' + request.statusText)); }; // If an error occurs request.onerror = () => { // Also deal with the case when the entire request fails to begin with // This is probably a network error, so reject the promise with an appropriate message reject(Error('There was a network error.')); }; request.onreadystatechange = function () { if (request.readyState == 4) { console.log("Load Complete >> ", media, "from", request.status); // Another callback here } }; // Every tick of the progress loader request.onprogress = data => console.log(data); // Send the request request.send(); }) } 

Он отлично работает и успешно загружается во всех средах, которые я его кормлю.

У меня только 1 проблема, и это в Chrome , когда я ссылаюсь на или который был предварительно загружен, он не вытаскивает его из кеша, а вместо этого перезагружает его с сервера. (IE9 даже вытаскивает из кеша)


Любые аудио и видео элементы всегда будут повторно загружаться с сервера …

   

Это всегда будет загружаться из кеша …


Вот два скриншота: один из хром и один из краев, показывающий активность сети из инструментов dev (оба были сброшены кэш-памяти до запуска) …

Хром введите описание изображения здесь

край введите описание изображения здесь

Основное отличие, которое я замечаю, – это статус запроса, который отличается между браузерами, когда дело доходит до предоставления контента (после предварительной загрузки). Но почему это так?

Я нашел это сообщение SO с 2013 года, в котором говорится, что:

Поскольку буферизация видео зависит от браузера, и поэтому она зависит от браузера и браузера.

Различные браузеры могут использовать разные факторы для определения сохранения или отказа от части буфера. Типичными факторами являются старые сегменты, дисковое пространство, память и производительность.

Это то, что здесь происходит? И если да, то кто-нибудь знает способ исправить это, чтобы хром всегда пытался вытащить видео из кеша?

Не уверен, что проблема кеширования – хромированная ошибка, но то, что вы делаете, кажется мне очень странным.

Вы предварительно загружаете свои носители или загружаете их полностью , но затем установите mediaElement в исходный источник.

Когда мы загружаем носитель через mediaElement ( или ), браузер будет делать запросы range , т. Е. Он не будет загружать полный файл, а только то, что ему нужно играть без перерыва.
Вот почему вы получаете ответы на 206 Partial content . Вероятно, поэтому хром не признает, что он является одним и тем же запросом, и, следовательно, не использует кеш еще раз. Я не уверен, что это хром-ошибка или нет .

Но так как вы уже загрузили полный файл, почему бы вам не установить sRc mediaElement в этот загруженный файл?

 // since you are setting the hr reponseType to `'blob'` mediaElement.src = URL.createObjectURL(request.response); // don't forget to URL.revokeObjectURL(mediaElement.src) when loaded 

Рабочий пример: (который вызывает странную ошибку на моем FF …)

 function loadVideo(url) { return new Promise((resolve, reject) => { // here we download it entirely let request = new XMLHttpRequest(); request.responseType = 'blob'; request.onload = (evt)=>resolve(request.response); request.onerror = reject; request.open('GET', url); request.send(); }).then((blob)=> new Promise((resolve, reject)=>{ resolve(URL.createObjectURL(blob)); // return the blobURL directly }) ); } loadVideo('https://dl.dropboxusercontent.com/s/bch2j17v6ny4ako/movie720p.mp4') .then(blobUrl => { // now it's loaded document.body.className = 'loaded'; let vid = document.querySelector('video'); vid.src = blobUrl; // we just set our mediaElement's src to this blobURL vid.onload = () => URL.revokeObjectURL(blobUrl); }).catch((err) => console.log(err)); 
 video{ display: none; } .loaded p{ display: none; } .loaded video{ display: unset; } 
 

loading.. please wait