MP3文件没有时间戳,因此没有提前知道的固有长度。 Chrome只是猜测,基于文件开头的比特率和文件的字节大小。它真的不知道。
有些球员不打扰猜测。
此外,由于Apple的一些令人难以置信的限制性政策,iOS上的所有浏览器都是Safari。因此,iOS上的Chrome实际上只是Safari Web视图的包装器。
哇,这是一个很难解决的问题。 (我花了几天时间。)
我了解到,不只是iOS出现了问题:Mac上的Safari也没有工作。
现在我觉得一切都适用于我测试过的每一个浏览器。
我很高兴找到了 这个例子 跟随。
这是我的答案:
/** * * @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; }