Например, предположим, что файл имеет длину 100 байт, и у меня есть все 100 байт. Тем не менее, я не знаю, каков должен быть ожидаемый размер файла, поэтому я запрашиваю файл и задаю заголовок Range, который выглядит следующим образом:
Ответ 2
Как Wrikken, это действительный запрос. Это также довольно часто, когда клиент запрашивает носитель или возобновляет загрузку.
Клиент будет часто тестировать, будет ли сервер обрабатывать запросы в диапазоне, а не просто искать ответ Accept-Ranges
. Chrome всегда отправляет Range: bytes=0-
с первым запросом GET для видео, поэтому его нельзя отклонить.
Всякий раз, когда клиент включает Range:
в свой запрос, даже если он искажен, он ожидает ответа частичного контента (206). Когда вы ищете вперед во время воспроизведения видео в формате HTML5, браузер запрашивает только начальную точку. Например:
Range: bytes=3744-
Итак, чтобы клиент правильно воспроизводил видео, ваш сервер должен иметь возможность обрабатывать эти неполные запросы диапазона.
Вы можете обрабатывать тип "диапазона", указанный в вашем вопросе, двумя способами:
Во-первых, вы можете ответить запрошенной отправной точкой, указанной в ответе, а затем общая длина файла минус единица (запрошенный диапазон байтов индексируется нулем). Например:
Запрос:
GET /BigBuckBunny_320x180.mp4
Range: bytes=100-
Ответ:
206 Partial Content
Content-Type: video/mp4
Content-Length: 64656927
Accept-Ranges: bytes
Content-Range: bytes 100-64656926/64656927
Во-вторых, вы можете ответить с исходной точкой, заданной в запросе, и длиной (размером) открытого файла. Это для веб-трансляций или других носителей, где общая длина неизвестна. Например:
Запрос:
GET /BigBuckBunny_320x180.mp4
Range: bytes=100-
Ответ:
206 Partial Content
Content-Type: video/mp4
Content-Length: 64656927
Accept-Ranges: bytes
Content-Range: bytes 100-64656926/*
Советы:
Вы всегда должны отвечать длиной контента, включенной в диапазон. Если диапазон завершен, с начала до конца, то длина содержимого будет просто разницей:
Запрос: Диапазон: байты = 500-1000
Ответ: Content-Range: байты 500-1000/123456
Помните, что диапазон индексируется нулевым значением, поэтому Range: bytes=0-999
на самом деле запрашивает 1000 байтов, а не 999, поэтому ответьте на что-то вроде:
Content-Length: 1000
Content-Range: bytes 0-999/123456
Или:
Content-Length: 1000
Content-Range: bytes 0-999/*
Но, если возможно, избегайте последнего метода, потому что некоторые медиаплееры пытаются определить продолжительность от размера файла. Если ваш запрос предназначен для медиаконтента, который является моей догадкой, тогда вы должны включить его продолжительность в ответ. Это делается в следующем формате:
X-Content-Duration: 63.23
Это должна быть плавающая точка. В отличие от Content-Length
, это значение не обязательно должно быть точным. Это помогало игроку искать видео. Если вы транслируете веб-трансляцию и только имеете общее представление о том, как долго она будет, лучше включить предполагаемую продолжительность, а не игнорировать ее вообще. Итак, для двухчасовой трансляции вы можете включить что-то вроде:
X-Content-Duration: 7200.00
С некоторыми типами носителей, такими как webm, вы также должны указать тип содержимого, например:
Content-Type: video/webm
Все это необходимо для правильного воспроизведения мультимедиа, особенно в HTML5. Если вы не даете длительности, игрок может попытаться определить продолжительность (чтобы обеспечить поиск) из своего размера файла, но это будет неточно. Это прекрасно и необходимо для трансляции веб-трансляций или прямой трансляции, но не идеально подходит для воспроизведения видеофайлов. Вы можете извлечь продолжительность с помощью программного обеспечения, такого как FFMPEG, и сохранить его в базе данных или даже в имени файла.
X-Content-Duration
прекращается в пользу Content-Duration
, поэтому я бы включил это тоже. Основной ответ на запрос "0-" будет включать по крайней мере следующее:
HTTP/1.1 206 Partial Content
Date: Sun, 08 May 2013 06:37:54 GMT
Server: Apache/2.0.52 (Red Hat)
Accept-Ranges: bytes
Content-Length: 3980
Content-Range: bytes 0-3979/3980
Content-Type: video/webm
X-Content-Duration: 2054.53
Content-Duration: 2054.53
Еще один момент: Chrome всегда начинает свой первый видео-запрос со следующим:
Range: bytes=0-
Некоторые серверы будут отправлять обычный ответ 200 в качестве ответа, который он принимает (но с ограниченными параметрами воспроизведения), но попытайтесь отправить 206 вместо этого, чтобы показывать, чем ваши серверные диапазоны. RFC 2616 говорит, что допустимо игнорировать заголовки диапазонов.