Browse Source

Prise en charge des requetes avec un entete Range et ajout de Accept-Ranges: bytes : fort utile pour la lecture de documents audio/video

pull/1/head
Cerdic 1 year ago
parent
commit
39ac374801
  1. 111
      action/api_docrestreint.php
  2. 2
      paquet.xml

111
action/api_docrestreint.php

@ -223,6 +223,7 @@ function accesrestreint_afficher_document(Accesrestreint_document $Document) {
$chemin_fichier = $Document->get_chemin_complet_fichier();
// toujours envoyer un content type, meme vide !
header('Accept-Ranges: bytes');
header('Content-Type: ' . $Document->get_mime_type());
// document décrit dans la table spip_documents ?
@ -255,11 +256,115 @@ function accesrestreint_afficher_document(Accesrestreint_document $Document) {
header('Expires: 3600'); // set expiration time
}
if ($size = filesize($chemin_fichier)) {
header('Content-Length: '. $size);
if (isset($_SERVER['HTTP_RANGE'])) {
accesrestreint_envoyer_partie($chemin_fichier, $Document->get_mime_type());
}
else {
if ($size = filesize($chemin_fichier)) {
header('Content-Length: '. $size);
}
readfile($chemin_fichier);
}
}
/**
* Prendre en charge l'entete Range:bytes=0-456 utilise par les player medias
* source : https://github.com/pomle/php-serveFilePartial/blob/master/ServeFilePartial.inc.php
*
* @param string $fileName
* @param string $contentType
* @throws Exception
*/
function accesrestreint_envoyer_partie($fileName, $contentType = 'application/octet-stream'){
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);
### 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('Chunksize became 0', 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();
}
readfile($chemin_fichier);
exit();
}

2
paquet.xml

@ -1,7 +1,7 @@
<paquet
prefix="accesrestreint"
categorie="auteur"
version="4.0.0"
version="4.1.0"
etat="test"
compatibilite="[3.1.0;3.3.*]"
logo="prive/themes/spip/images/accesrestreint-64.png"

Loading…
Cancel
Save