Range header support / video #2094

Open
opened 2026-10-05 01:06:12 +02:00 by adam · 0 comments
Owner

When using plugins such as piwigo-videojs -- it appears that action.php is called by the browser with range-headers (and a connection keep alive) as to avoid fetching the entire video in one go.

And if the video is larger than around 500 Mbyte - then a fetch for less than that (e.g the "Range 0-1" that piwigo-videojs ) will be rejected in the browser. Because it is much larger than the N bytes it expects/asked.

The net result is that larger videos do not play; or if they play - after the whole thing is downloaded.

The quick hack below (to get something working) made things work for me. I.e with this videos of any size will load and play (quickly); in Safari, Brave, Chrome and Firefox.

They consist changes consist of:

  1. replacing the readfile() by a byte range version and not flushing the buffer just yet

  2. adding a range header library from https://github.com/rvflorian/byte-serving-php with a small tweak as to reintroduce the buffer flushing (though I am not sure it is needed) and neutering its mime type cleverness.

  3. Changes to the action.php

--- action.php.ok	2025-09-21 19:20:19.436609000 +0000
+++ action.php	2025-09-21 20:12:12.515317000 +0000
@@ -9,6 +9,7 @@
 define('PHPWG_ROOT_PATH','./');
 session_cache_limiter('public');
 include_once(PHPWG_ROOT_PATH.'include/common.inc.php');
+include_once(PHPWG_ROOT_PATH.'include/range.inc.php');
 
 // Check Access and exit when user status is not ok
 check_status(ACCESS_GUEST);
@@ -224,14 +225,20 @@
   @set_time_limit(0);
 }
 
+
 // Without clean and flush there may be some image download problems, or image can be corrupted after download
 if (ob_get_length() !== FALSE)
 {
   ob_flush();
 }
-flush();
-ob_end_flush();
 
-@readfile($file);
+byteserve($file, 0, -1, $ctype);
+
+// Moved to byteserve
+// flush();
+// ob_end_flush();
+
+
+// @readfile($file);
 
 ?>
  1. Changes to https://github.com/rvflorian/byte-serving-php
72c72
<  function byteserve_buffered_read($file, $bytes, $buffer_size=1024)
---
>  function byteserve_buffered_read($file, $bytes, $buffer_size=4 * 1024 * 1024)
73a74,76
> flush();
> ob_end_flush();
> 
124c127
<      $mimetype = mime_content_type($filename);
---
>      /* $mimetype = mime_content_type($filename); */
204a208
> 

One probably also wants to change the buffer_size to something like 1-10 Mbyte for video.

When using plugins such as piwigo-videojs -- it appears that action.php is called by the browser with range-headers (and a connection keep alive) as to avoid fetching the entire video in one go. And if the video is larger than around 500 Mbyte - then a fetch for less than that (e.g the "Range 0-1" that piwigo-videojs ) will be rejected in the browser. Because it is much larger than the N bytes it expects/asked. The net result is that larger videos do not play; or if they play - after the whole thing is downloaded. The quick hack below (to get something working) made things work for me. I.e with this videos of any size will load and play (quickly); in Safari, Brave, Chrome and Firefox. They consist changes consist of: 1) replacing the readfile() by a byte range version and not flushing the buffer just yet 2) adding a range header library from https://github.com/rvflorian/byte-serving-php with a small tweak as to reintroduce the buffer flushing (though I am not sure it is needed) and neutering its mime type cleverness. 1) Changes to the action.php ``` --- action.php.ok 2025-09-21 19:20:19.436609000 +0000 +++ action.php 2025-09-21 20:12:12.515317000 +0000 @@ -9,6 +9,7 @@ define('PHPWG_ROOT_PATH','./'); session_cache_limiter('public'); include_once(PHPWG_ROOT_PATH.'include/common.inc.php'); +include_once(PHPWG_ROOT_PATH.'include/range.inc.php'); // Check Access and exit when user status is not ok check_status(ACCESS_GUEST); @@ -224,14 +225,20 @@ @set_time_limit(0); } + // Without clean and flush there may be some image download problems, or image can be corrupted after download if (ob_get_length() !== FALSE) { ob_flush(); } -flush(); -ob_end_flush(); -@readfile($file); +byteserve($file, 0, -1, $ctype); + +// Moved to byteserve +// flush(); +// ob_end_flush(); + + +// @readfile($file); ?> ``` 2) Changes to https://github.com/rvflorian/byte-serving-php ``` 72c72 < function byteserve_buffered_read($file, $bytes, $buffer_size=1024) --- > function byteserve_buffered_read($file, $bytes, $buffer_size=4 * 1024 * 1024) 73a74,76 > flush(); > ob_end_flush(); > 124c127 < $mimetype = mime_content_type($filename); --- > /* $mimetype = mime_content_type($filename); */ 204a208 > ``` One probably also wants to change the buffer_size to something like 1-10 Mbyte for video. <!-- github-sync-id:3438577476 -->
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: adam/Piwigo#2094