Можно ли дождаться полной загрузки
У меня есть видеофайл (пример, 25 МиБ) — я заранее знаю, что он небольшой и поместится в кэш, но для усложения задачи предположим, что его длительность заранее не известна (другой пример, тоже 25 МиБ). Я хочу дождаться его полной загрузки и только после этого начать воспроизведение, чтобы гарантированно ничего не лагало, например.
К своему большому удивлению я обнаружил, что у тега <video> отсутствует событие load. Есть события progress, loadeddata и canplaythrough, но что с ними делать — непонятно. Мне попадались попытки посчитать окончание загрузки по сравнению длительности, но, во-первых, в надёжности этого метода есть сомнения, а во-вторых, это не сработает, если длительность в принципе неизвестна.
В связи с этим у меня возникают вопросы:
- будет ли браузер в принципе загружать видеофайл до конца, или он его всего лишь немного забуферизует?
- если будет, то можно ли отловить момент завершения загрузки?
- если не будет, то можно ли отловить момент, когда браузер перестал совершать дальнейшую загрузку? (UPD: нашёл событие
suspend, но вопрос про полную загрузку ещё актуален)
Ниже в два одинаковых сниппета с разными видеофайлами для поиграться.
const video = document.getElementById("video");
video.onload = () => console.log("onload не срабатывает");
video.onprogress = (event) => {
console.log(`progress ${event.timeStamp}, duration: ${video.duration}`);
};
video.onloadeddata = () => console.log("loadeddata");
video.oncanplaythrough = () => console.log("canplaythrough");
video.onsuspend = () => console.log("suspend");
<video
id="video"
src="https://andreymal.org/files/bbb-test/bbb-with-duration.mp4"
controls
preload="auto"
style="margin-bottom: 100vh">
</video>
const video = document.getElementById("video");
video.onload = () => console.log("onload не срабатывает");
video.onprogress = (event) => {
console.log(`progress ${event.timeStamp}, duration: ${video.duration}`);
};
video.onloadeddata = () => console.log("loadeddata");
video.oncanplaythrough = () => console.log("canplaythrough");
video.onsuspend = () => console.log("suspend");
<video
id="video"
src="https://andreymal.org/files/bbb-test/bbb-without-duration.mp4"
controls
preload="auto"
style="margin-bottom: 100vh">
</video>
Ответы (1 шт):
- Нет, браузер грузит кусок файла и останавливает загрузку.
- Можно попробовать загрузить файл самостоятельно через fetch.
- Из скачанных через fetch данных можно создать ссылку - тогда уж точно все данные будут и не потребуется полагаться на кэширование.
fetch("//andreymal.org/files/bbb-test/bbb-with-duration.mp4")
.then(resp => resp.blob())
.then(blob => {
var video = document.querySelector('video')
video.src = URL.createObjectURL(blob)
video.hidden = false
video.play()
})
video { display: block; max-height: calc(100vh - 16px); margin: auto; }
<video controls hidden muted>