HTML5 элемент видео не запрашивает конец диапазона
У меня есть <video>
а также <audio>
элемент, который загружает файл (mp4, mp3, не имеет значения) с моего сервера через запросы Range.
Однако кажется, что элемент запрашивает только конечный диапазон с моего сервера, и оттуда пытается выполнить потоковую передачу напрямую с байтов 0 до конца, в результате чего проигрыватель застревает в "цикле загрузки", что заставляет браузер приостановить все другие действия, пока загрузка не будет завершена.
Кто-нибудь знает решение этой проблемы? Должен ли я, например, сделать мой запрос потока фактическим концом его 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
тогда может вызвать сжатие, которое отключит заголовки диапазона