Видео HTML5 не буферизует достаточное количество данных во время воспроизведения

#javascript #html #node.js #express #video-streaming

Вопрос:

Редактировать

В первоначальном вопросе и тестировании для всего этого использовался Chrome. Похоже, что использование Firefox с некоторым незначительным тестированием теперь обеспечивает более последовательную загрузку, чем Chrome, где буферизованная часть видео будет постоянно оставаться на гораздо большем куске даже при поиске. Добавляю это на случай, если кто-то еще сочтет это полезным или сможет проверить результаты (возможно, также с помощью большего количества браузеров).

TL;DR:

Как я могу заставить видео буферизировать больше данных во время воспроизведения? Желательно, чтобы я также хотел, чтобы он сохранял буферизацию данных даже во время паузы.

Итак, у меня есть довольно простая доставка видеоконтента с экспресс-сервера, работающего на узле. Смысл в том, чтобы пользователь запросил конкретное видео, используя идентификатор, а затем сервер передал файлы mp4 в тег видео HTML5 на интерфейсе. Все это работает безупречно, за исключением одной небольшой жалобы.

Первоначально, когда видео загружается пользователем, буферизованная часть видео значительно больше, чем в любое другое время после этого (светло-серый цвет-это визуальное представление диапазона HTML5Video.buffered).

Начальная буферизация видео

Теперь, если видео продолжит воспроизводиться после этой первоначально загруженной точки, оно загрузит с сервера только очень небольшие фрагменты, даже если размер фрагмента установлен на 10 МБ, а все тестовое видео составляет всего 30 МБ! (Буферизованная часть теперь будет постоянно оставаться на этом уровне в течение всего прохождения).

меньшая буферизованная часть

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

Вот конкретный код, который позволяет передавать видеофайл в потоковом режиме:

 app.get("/source", (req, res) => {
    ...

    if (!req.headers.range) {
        return res.sendStatus(416);
    }
    
    ...

    const sourcePath = getSourcePath();
    const sourceSize = fs.statSync(sourcePath).size;

    const CHUNK_SIZE = 10000000; // 10M bytes / 10MB
    const start = Number(req.headers.range.replace(/D/g, ""));
    const end = Math.min(start   CHUNK_SIZE, sourceSize - 1);
  
    const contentLength = (end - start)   1;
    const headers = {
        "Accept-Ranges": "bytes",
        "Connection": "keep-alive",
        "Content-Length": contentLength,
        "Content-Range": `bytes ${start}-${end}/${sourceSize}`,
        "Content-Type": "video/mp4",
    };
  
    res.writeHead(206, headers);
    fs.createReadStream(sourcePath, { start, end }).pipe(res);
});
 

And the data is requested from Express using a simple HTML5 video element:

 <video id="videoPlayer" class="video">
    <source src="/source<%= src %>" type="video/mp4" />
</video>
 

The src here is gotten in an .ejs template file, not important to the code overall.