Видеоклип HTML повторно загружает видеофайл - PullRequest
7 голосов
/ 27 октября 2019

У меня есть видео HTML5, которое довольно большое. Я также использую Chrome. Элемент video имеет атрибут loop, но каждый раз, когда видео «зацикливается», браузер повторно загружает видеофайл. Я установил Cache-Control "max-age=15768000, private". Однако это не предотвращает каких-либо дополнительных загрузок идентичного файла. Я использую Amazon S3 для размещения файла. Также сервер s3 отвечает заголовком Accepts Ranges, который вызывает несколько сотен частичных загрузок файла с кодом ответа 206 http.

Вот мой тег видео:

<video autoplay="" loop="" class="asset current">
    <source src="https://mybucket.s3.us-east-2.amazonaws.com/myvideo.mp4">
</video>

ОБНОВЛЕНИЕ:

Похоже, что лучшее решение состоит в том, чтобы предотвратить отправку заголовка Accept Ranges с исходным ответоми вместо этого используйте код ответа 200 http. Как этого добиться, чтобы видео полностью кэшировалось через файл .htaccess?

Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 15 ноября 2019

Я не знаю точно, с какой реальной проблемой вы сталкиваетесь.

Возможно, Chrome имеет максимальный размер кеша, и если это так, то нетиспользование Range-Requests ничего не решит.

Другое возможное объяснение состоит в том, что кэширование мультимедиа на самом деле не простая задача.
Без просмотра вашего файла трудно точно сказать, в каком случае вы находитесь, но вам нужнопонимать, что для воспроизведения мультимедиа браузеру не нужно извлекать весь файл.
Например, вы можете очень хорошо воспроизвести видеофайл в элементе , поскольку видеопоток не будет использоваться,браузер вполне может опустить его полностью и загрузить только аудиопоток. Не уверен, если кто-нибудь, но они могли бы. Большинство форматов мультимедиа физически разделяют аудио- и видеопотоки в файле, и их позиции байтов отмечены в метаданных.
Они, безусловно, могут кэшировать выполняемые ими Range-запросы, но я думаю, что они по-прежнему довольно редки.

Но, как бы ни было заманчиво отключить Range-Requests, вы должны знать, что некоторые браузеры (Safari) не будут воспроизводить ваши медиаданные, если ваш сервер не разрешает Range-Requests.
Так что даже тогдавероятно, это не то, что вам нужно.


Первое, что вы можете попробовать - оптимизировать видео для использования в Интернете. Вместо mp4, подайте файл webm. Обычно они занимают меньше места для того же качества, и, возможно, вы избежите ограничения max-size .

Если полученный файл все еще слишком велик, то грязным решением будет использование MediaSource, чтобы файл оставался в памяти и вам нужно было извлечь его только один раз.

В следующем примере файл будет извлечен целиком только один раз, кусками по 1 МБ, которые будут переданы MediaSource по мере его выборки, а затем для циклического воспроизведения будут использоваться только данные в памяти:

document.getElementById('streamVid').onclick = e => (async () => {

const url = 'https://upload.wikimedia.org/wikipedia/commons/transcoded/2/22/Volcano_Lava_Sample.webm/Volcano_Lava_Sample.webm.360p.webm';
// you must know the mimeType of your video before hand.
const type = 'video/webm; codecs="vp8, vorbis"';
if( !MediaSource.isTypeSupported( type ) ) {
  throw 'Unsupported';
}

const source = new MediaSource();
source.addEventListener('sourceopen', sourceOpen);
document.getElementById('out').src = URL.createObjectURL( source );

// async generator Range-Fetcher
async function* fetchRanges( url, chunk_size = 1024 * 1024 ) {
  let chunk = new ArrayBuffer(1);
  let cursor = 0;
  while( chunk.byteLength ) {
    const resp = await fetch( url, {
      method: "get",
        headers: { "Range": "bytes=" + cursor + "-" + ( cursor += chunk_size ) }
      }
    )
    chunk = resp.ok && await resp.arrayBuffer();
    cursor++; // add one byte for next iteration, Ranges are inclusive
    yield chunk;
  }
}
// set up our MediaSource
async function sourceOpen() {
  const buffer = source.addSourceBuffer( type );
//  buffer.mode = "sequence";
  // waiting forward to appendAsync...
  const appendBuffer = ( chunk ) => {
    return new Promise( resolve => {
      buffer.addEventListener( 'update', resolve, { once: true } );
      buffer.appendBuffer( chunk );
    } );
  }
  // while our RangeFetcher is running
  for await ( const chunk of fetchRanges(url) ) {
    if( chunk ) { // append to our MediaSource
      await appendBuffer( chunk );
    }
    else { // when done
      source.endOfStream();
    }
  }
}
})().catch( console.error );
<button id="streamVid">stream video</button>
<video id="out" controls muted autoplay loop></video>
0 голосов
/ 13 ноября 2019

У Google Chrome есть ограничение на размер файла. В этом случае мой предыдущий ответ не сработает. Вы должны использовать что-то вроде file-compress , этот ресурс может сжимать файл настолько, что он позволяет использовать файловый кеш. Веб-браузер может иметь новый размер кэша, установленный вручную, однако это невозможно, если конечный пользователь не назначил свой кэш для согласования с пространством, необходимым для хранения длинного видео.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...