Ого, это была очень сложная проблема.(Это заняло у меня несколько дней.)
И я узнал, что проблемы были не только с iOS: Safari на Mac тоже не работал.
Теперь я думаю, что все работает на каждом браузере, который я тестировал.
Я действительно рад, что нашел этот пример для подражания.
Здесьмой ответ:
/**
*
* @param string $disk
* @param string $filename
* @return \Illuminate\Http\Response|\Illuminate\Contracts\Routing\ResponseFactory|\Symfony\Component\HttpFoundation\StreamedResponse
*/
public static function getMediaFile($disk, $filename) {
$rangeHeader = request()->header('Range');
$fileContents = Storage::disk($disk)->get($filename);
$fullFilePath = Storage::disk($disk)->path($filename); //https://stackoverflow.com/a/49532280/470749
$headers = ['Content-Type' => Storage::disk($disk)->mimeType($fullFilePath)];
if ($rangeHeader) {
return self::getResponseStream($disk, $fullFilePath, $fileContents, $rangeHeader, $headers);
} else {
$httpStatusCode = 200;
return response($fileContents, $httpStatusCode, $headers);
}
}
/**
*
* @param string $disk
* @param string $fullFilePath
* @param string $fileContents
* @param string $rangeRequestHeader
* @param array $responseHeaders
* @return \Symfony\Component\HttpFoundation\StreamedResponse
*/
public static function getResponseStream($disk, $fullFilePath, $fileContents, $rangeRequestHeader, $responseHeaders) {
$stream = Storage::disk($disk)->readStream($fullFilePath);
$fileSize = strlen($fileContents);
$fileSizeMinusOneByte = $fileSize - 1; //because it is 0-indexed. https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.16
list($param, $rangeHeader) = explode('=', $rangeRequestHeader);
if (strtolower(trim($param)) !== 'bytes') {
abort(400, "Invalid byte range request"); //Note, this is not how https://stackoverflow.com/a/29997555/470749 did it
}
list($from, $to) = explode('-', $rangeHeader);
if ($from === '') {
$end = $fileSizeMinusOneByte;
$start = $end - intval($from);
} elseif ($to === '') {
$start = intval($from);
$end = $fileSizeMinusOneByte;
} else {
$start = intval($from);
$end = intval($to);
}
$length = $end - $start + 1;
$httpStatusCode = 206;
$responseHeaders['Content-Range'] = sprintf('bytes %d-%d/%d', $start, $end, $fileSize);
$responseStream = response()->stream(function() use ($stream, $start, $length) {
fseek($stream, $start, SEEK_SET);
echo fread($stream, $length);
fclose($stream);
}, $httpStatusCode, $responseHeaders);
return $responseStream;
}