Для достижения функции воспроизведения видео, а также операции загрузки больших файлов, мы не можем избежать одного момента: для получения данных из любого местоположения файла, если мы просто передадим содержимое файла echo , этот метод можно использовать только для загрузки файлов. Если видеофайл используется для воспроизведения, с ним трудно справиться. Специфическая производительность заключается в том, что индикатор выполнения не может быть отрегулирован во время воспроизведения видео. Более того, если веб-сайт видео использует только каталог, к которому можно получить прямой доступ, то видео также эквивалентно общедоступности. Для чего VIP Нет никакой возможности говорить о чем-либо. В этой статье будет Диапазон Для обеспечения зависящей от технологии реализации воспроизведения видео, непрерывной передачи точек останова и многопоточной загрузки
Диапазон
В протоколе HTTP поддержка Диапазон Синтаксический формат выглядит следующим образом. См. диапазон: MDN для получения подробной информации:
Range:= - Range: = - Range: = - , - Range: = - , - , -
<единица измерения>Может быть толькобайт(на данный момент), обозначенные единицы измерения<диапазон-начало>Целое число, представляющее начальное значение диапазона в определенной единице измерения.<конец диапазона>Целое число, представляющее конечное значение диапазона в определенной единице измерения. Это значение не является обязательным. Если он не существует, это означает, что диапазон простирается до конца документа.
Например: получить 0-100 Байтовые данные и 120 для завершения данных
Range: bytes=0-100,120-
Диапазон содержимого
Заголовок определяет диапазон содержимого данных ответа. Формат синтаксиса выглядит следующим образом:
Content-Range:- / Content-Range: - /* Content-Range: */
Объяснять:
<единица измерения>Единица измерения, используемая в диапазоне данных. Обычно байты.<диапазон-начало>Целое число, представляющее начальное значение интервала в заданной единице измерения.<конец диапазона>Целое число, представляющее конечное значение интервала в заданной единице измерения.<размер>Размер всего файла (используйте, если размер неизвестен"*"Представление)
Например:
Content-Range: bytes 200-1000/67589
Многодиапазонный отклик
Это не упоминается в сети, но протокол HTTP поддерживает несколько диапазонов. Конкретный формат возвращаемой информации о содержимом выглядит следующим образом:
GET http://suda.dev.dx/file HTTP/1.1 Host: suda.dev.dx Connection: keep-alive Accept-Encoding: identity;q=1, *;q=0 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3679.0 Safari/537.36 Accept: */* Referer: http://test.dev.dx/video.html Accept-Language: zh-CN,zh;q=0.9 Cookie: php_session=8eec314af63d994c2eeb1baca7487332 Range: bytes=0-1,2-3 HTTP/1.1 206 Partial Content Date: Sun, 10 Mar 2019 09:36:59 GMT Server: Apache/2.4.23 (Win32) OpenSSL/1.0.2j mod_fcgid/2.3.9 X-Powered-By: PHP/7.2.1 Accept-Ranges: bytes Content-Length: 220 Keep-Alive: timeout=5, max=100 Connection: Keep-Alive Content-Type: multipart/byteranges; boundary=multiple_range_ss6bBSB6IlLi0YPpP8rK3g== --multiple_range_ss6bBSB6IlLi0YPpP8rK3g== Content-Type: video/mp4 Content-Range: bytes 0-1/132006090 <...somedata...> --multiple_range_ss6bBSB6IlLi0YPpP8rK3g== Content-Type: video/mp4 Content-Range: bytes 2-3/132006090 <...somedata...>
Принять-Диапазоны
Сервер отвечает и сообщает браузеру, поддерживает ли он Диапазон ,
Синтаксис:
Accept-Ranges: bytes Accept-Ranges: none
- нет Единица запроса области не поддерживается и используется редко, поскольку это эквивалентно отказу от возврата этого заголовка. Однако некоторые браузеры, такие как IE9, отключат или удалят кнопку паузы в диспетчере загрузок в соответствии с этим заголовком.
- байты Запрос диапазона в байтах
Код реализации
Этот код реализации можно просто понять как псевдокод, некоторые зависимости не указаны, Swoole Его можно использовать после внесения изменений в окружающую среду.
Используйте код:
onRequest($request, $response);
}
}Код зависимости:
file = $file instanceof SplFileObject? $file : new SplFileObject($file);
$this->mime = MimeType::getMimeType($this->file->getExtension());
}
/**
*Processing file requests
*
* @param \suda\framework\Request $request
* @param \suda\framework\Response $response
* @return void
*/
public function onRequest(Request $request, Response $response)
{
$ranges = $this->getRanges($request);
$response->setHeader('accept-ranges', 'bytes');
if ($ranges === false || $request->getMethod() !== 'GET') {
$response->status(400);
} elseif ($ranges === null) {
$response->sendFile($this->file->getRealPath());
} elseif (count($ranges) === 1) {
$response->status(206);
$range = $ranges[0];
$response->setHeader('content-type', $this->mime);
$response->setHeader('content-range', $this->getRangeHeader($range));
$this->sendFileByRange($response, $range);
} else {
$response->status(206);
$this->sendMultipleFileByRange($response, $ranges);
}
}
/**
*Send multi range
*
* @param \suda\framework\Response $response
* @param array $ranges
* @return void
*/
protected function sendMultipleFileByRange(Response $response, array $ranges)
{
$separates = 'multiple_range_'.base64_encode(\md5(\uniqid(), true));
$response->setHeader('content-type', 'multipart/byteranges; boundary='.$separates);
foreach ($ranges as $range) {
$response->write('--'.$separates."\r\n");
$this->sendMultipleRangePart($response, $range);
$this->sendFileByRange($response, $range);
$response->write("\r\n");
}
}
/**
*Send range data
*
* @param \suda\framework\Response $response
* @param array $range
* @return void
*/
protected function sendFileByRange(Response $response, array $range)
{
$response->write(new DataStream($this->file->getRealPath(), $range['start'], $range['end'] - $range['start'] + 1));
}
/**
*Get range description
*
* @param \suda\framework\Request $request
* @return array|bool|null
*/
protected function getRanges(Request $request)
{
$ranges = $this->parseRangeHeader($request);
if (\is_array($ranges)) {
return $this->parseRanges($ranges);
} elseif ($ranges === false) {
return false;
}
return null;
}
/**
*Write range header
*
* @param \suda\framework\Response $response
* @param array $range
* @return void
*/
protected function sendMultipleRangePart(Response $response, array $range)
{
$response->write('Content-Type: '.$this->mime."\r\n");
$response->write('Content-Range: '.$this->getRangeHeader($range) ."\r\n\r\n");
}
/**
*Generate range header
*
* @param array $range
* @return string
*/
protected function getRangeHeader(array $range):string
{
return sprintf('bytes %d-%d/%d', $range['start'], $range['end'], $this->file->getSize());
}
/**
*Get range description
*
* @param \suda\framework\Request $request
* @return array|bool|null
*/
protected function parseRangeHeader(Request $request)
{
$range = $request->getHeader('range', null);
if (is_string($range)) {
$range = trim($range);
if (\strpos($range, 'bytes=') !== 0) {
return false;
}
$rangesFrom = \substr($range, strlen('bytes='));
return \explode(',', $rangesFrom);
}
return null;
}
/**
*Processing scope
*
* @param array $ranges
* @return array|bool
*/
protected function parseRanges(array $ranges)
{
$range = [];
foreach ($ranges as $value) {
if (($r = $this->parseRange($value)) !== null) {
$range[] = $r;
} else {
return false;
}
}
return $range;
}
/**
*Process range
*
* @param string $range
* @return array
*/
protected function parseRange(string $range):?array
{
$range = trim($range);
if (strrpos($range, '-') === strlen($range) - 1) {
return [
'start' => intval(\rtrim($range, '-')),
'end' => $this->file->getSize() - 1,
];
} elseif (\strpos($range, '-') !== false) {
list($start, $end) = \explode('-', $range, 2);
return ['start' => intval($start) , 'end' => intval($end) ];
}
return null;
}
}Ссылка
- Ссылка
- Ссылка
- https://developer.mozilla.org…
- https://developer.mozilla.org…
- Полный код