HTML5 элемент видео не запрашивает конец диапазона

У меня есть <video> а также <audio> элемент, который загружает файл (mp4, mp3, не имеет значения) с моего сервера через запросы Range.

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

Диапазон запроса 1

Диапазон запроса 2

Кто-нибудь знает решение этой проблемы? Должен ли я, например, сделать мой запрос потока фактическим концом его content length или же accept-ranges?

Вот полный список запросов от Chrome, и внизу вы можете увидеть, что запрос на URL view?watch=v__AAAAAA673pxX просто остается в ожидании, в основном до тех пор, пока element,

Полная история запросов

В двух словах: элементы html5 застряли в цикле загрузки при использовании http-range запросы и заставить все другие запросы оставаться "в ожидании".

ОБНОВИТЬ

Проблема была решена на стороне сервера.

Принимая во внимание, что оригинальная функция потока буквально выводила бы каждый байт, я изменил код, чтобы вывести ТОЛЬКО размер фактического буфера. Это заставляет elements сделать новый запрос на оставшиеся данные.

Важным примечанием здесь является возвращение content-length, accept-ranges а также content-ranges которые соответствуют размеру файла, начальной и конечной позиции в каждом HTTP RANGE запрос.

Для будущих ссылок:

function stream(){
    $i = $this->start;
    set_time_limit(0);
    while(!feof($this->stream) && $i <= $this->end) {
        $bytesToRead = $this->buffer;
        if(($i+$bytesToRead) > $this->end) {
            $bytesToRead = $this->end - $i + 1;
        }
        $data = fread($this->stream, $bytesToRead);
        echo $data;
        flush();
        $i += $bytesToRead;
    }
}

новая функция потока:

function stream()
{
    //added a time limit for safe-guarding
    set_time_limit(3);
    echo fread($this->stream, $this->offset);
    flush();
}

1 ответ

Предположим, у вас есть видео размером 1 Мб. Когда вы запрашиваете видео для браузера в первый раз, он отправит заголовки, подобные этому.

Host:localhost
Range:bytes=0-

Заголовок диапазона bytes=0- означает, что браузер запрашивает у сервера возврат до того, что он может вернуть, т.е. конечная позиция не указана

На этот сервер обычно отвечают целым файлом, кроме последнего байта, чтобы сохранить контекст диапазона

Accept-Ranges:bytes
Content-Length:99999
Content-Range:bytes 0-99999/1000000

Теперь предположим, что ваше видео загружено до 30%, а вы ищете до 70%, тогда браузер запросит, чтобы заголовок части был таким

Host:localhost
Range:bytes=700000-

Однако кажется, что элемент запрашивает только конечный диапазон с моего сервера,

Вы можете видеть, что вы сделали неверный вывод, что это начальная позиция видео части

Теперь сервер может ответить как

Accept-Ranges:bytes
Content-Length:300000
Content-Range:bytes 700000-99999/1000000

Заметка Content-Range он явно указывает, какая часть файла. Так что я предполагаю, что ваш сервер не отправляет эту информацию и браузер прослушивается. Также иногда MIME-типы могут также вызвать проблемы, попробуйте использовать точный MIME-тип вашего файла, как Content-Type: video/mp4.Если вы используете Content-Type: application/octet-stream тогда может вызвать сжатие, которое отключит заголовки диапазона

Другие вопросы по тегам