Created
August 19, 2023 13:44
-
-
Save renalpha/a4092c7fd205dfb13f84c70edb079663 to your computer and use it in GitHub Desktop.
Ionic Capacitor <video> remote URL IOS Android
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
return [ | |
/* | |
|-------------------------------------------------------------------------- | |
| Cross-Origin Resource Sharing (CORS) Configuration | |
|-------------------------------------------------------------------------- | |
| | |
| Here you may configure your settings for cross-origin resource sharing | |
| or "CORS". This determines what cross-origin operations may execute | |
| in web browsers. You are free to adjust these settings as needed. | |
| | |
| To learn more: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS | |
| | |
*/ | |
'paths' => ['api/*', 'sanctum/csrf-cookie', 'video/*'], | |
'allowed_methods' => ['*'], | |
'allowed_origins' => ['*'], | |
'allowed_origins_patterns' => [], | |
'allowed_headers' => ['*'], | |
'exposed_headers' => false, | |
'max_age' => false, | |
'supports_credentials' => false, | |
]; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<video autoplay loop muted playsinline preload="metadata" webkit-playsinline="webkit-playsinline"> | |
<source src="https://yoururl.test/video/smallerbg-te.mp4" type="video/mp4"/> | |
</video> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Route::get('/video/{video}', function (Request $request, $video) { | |
$fileName = storage_path('video/' . $video); | |
$contentType = mime_content_type($fileName); | |
$fileTitle = basename($fileName); | |
if (!file_exists($fileName)) { | |
throw new \Exception(sprintf('File not found: %s', $fileName)); | |
} | |
if (!is_readable($fileName)) { | |
throw new \Exception(sprintf('File not readable: %s', $fileName)); | |
} | |
### Remove headers that might unnecessarily clutter up the output | |
header_remove('Cache-Control'); | |
header_remove('Pragma'); | |
### Default to send entire file | |
$byteOffset = 0; | |
$byteLength = $fileSize = filesize($fileName); | |
header('Accept-Ranges: bytes', true); | |
header(sprintf('Content-Type: %s', $contentType), true); | |
if ($fileTitle) { | |
header(sprintf('Content-Disposition: attachment; filename="%s"', $fileTitle)); | |
} | |
### Parse Content-Range header for byte offsets, looks like "bytes=11525-" OR "bytes=11525-12451" | |
if (isset($_SERVER['HTTP_RANGE']) && preg_match('%bytes=(\d+)-(\d+)?%i', $_SERVER['HTTP_RANGE'], $match)) { | |
### Offset signifies where we should begin to read the file | |
$byteOffset = (int)$match[1]; | |
### Length is for how long we should read the file according to the browser, and can never go beyond the file size | |
if (isset($match[2])) { | |
$finishBytes = (int)$match[2]; | |
$byteLength = $finishBytes + 1; | |
} else { | |
$finishBytes = $fileSize - 1; | |
} | |
$cr_header = sprintf('Content-Range: bytes %d-%d/%d', $byteOffset, $finishBytes, $fileSize); | |
header("HTTP/1.1 206 Partial content"); | |
header($cr_header); ### Decrease by 1 on byte-length since this definition is zero-based index of bytes being sent | |
} | |
$byteRange = $byteLength - $byteOffset; | |
header(sprintf('Content-Length: %d', $byteRange)); | |
header(sprintf('Expires: %s', date('D, d M Y H:i:s', time() + 60 * 60 * 24 * 90) . ' GMT')); | |
$buffer = ''; ### Variable containing the buffer | |
$bufferSize = 512 * 16; ### Just a reasonable buffer size | |
$bytePool = $byteRange; ### Contains how much is left to read of the byteRange | |
if (!$handle = fopen($fileName, 'r')) { | |
throw new \Exception(sprintf("Could not get handle for file %s", $fileName)); | |
} | |
if (fseek($handle, $byteOffset, SEEK_SET) == -1) { | |
throw new \Exception(sprintf("Could not seek to byte offset %d", $byteOffset)); | |
} | |
while ($bytePool > 0) { | |
$chunkSizeRequested = min($bufferSize, $bytePool); ### How many bytes we request on this iteration | |
### Try readin $chunkSizeRequested bytes from $handle and put data in $buffer | |
$buffer = fread($handle, $chunkSizeRequested); | |
### Store how many bytes were actually read | |
$chunkSizeActual = strlen($buffer); | |
### If we didn't get any bytes that means something unexpected has happened since $bytePool should be zero already | |
if ($chunkSizeActual == 0) { | |
### For production servers this should go in your php error log, since it will break the output | |
trigger_error(sprintf("Chunksize became 0 in %s with byteOffset %s, byteRange %s, byteLength %s", $fileName, $byteOffset, $byteRange, $byteLength), E_USER_WARNING); | |
break; | |
} | |
### Decrease byte pool with amount of bytes that were read during this iteration | |
$bytePool -= $chunkSizeActual; | |
### Write the buffer to output | |
print $buffer; | |
### Try to output the data to the client immediately | |
flush(); | |
} | |
exit(); | |
})->where('video', '.*.mp4$'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The reason why this doesnt work out of the box is because of PartialContent.
You should first test your URL endpoint through Safari.
This took me days to fix.