1

i'm trying to run a video through php file.
it's worked.
but the problem is that when i try to go to special time in video it replay the video from the beginning.
i have 2 php files to do this. first file named "index.php" here is it's code:

<?php
    $vids = ['asbiudsaudsausbdisa' => 'video_1'];
?>
<!DOCTYPE html>
<html>
  <body>
    <video src="videos.php?h=asbiudsaudsausbdisa" controls></video>
  </body>
</html>

second file named "videos.php" here is it's code :

<?php
$vids = ['asbiudsaudsausbdisa' => 'video.mp4'];
    
$filehash = $_GET['h'];
$filename = $vids[$filehash];
$vd = $filename; 
readfile($vd);

$file = $filename;

$filesize = filesize($file);

$offset = 0;

$length = $filesize;


if ( isset($_SERVER['HTTP_RANGE']) ) { 
// if the HTTP_RANGE header is set we're dealing with partial content
    $partialContent = true;
    // find the requested range
    // this might be too simplistic, apparently the client can request
    // multiple ranges, which can become pretty complex, so ignore it for now
    preg_match('/bytes=(\d+)-(\d+)?/', $_SERVER['HTTP_RANGE'], $matches);

    $offset = intval($matches[1]);
    $length = intval($matches[2]) - $offset;

} else {
    $partialContent = false;
}

$file = fopen($file, 'r');

// seek to the requested offset, this is 0 if it's not a partial content request
fseek($file, $offset);

$data = fread($file, $length);

fclose($file);

if ( $partialContent ) {
    // output the right headers for partial content

    header('HTTP/1.1 206 Partial Content');

    header('Content-Range: bytes ' . $offset . '-' . ($offset + $length) . '/' . $filesize);
    
}
    
header('Content-Type: ' . $ctype);
header('Content-Length: ' . $filesize);
header('Content-Type: video/mp4');
header('Accept-Ranges: bytes');

?>

what i have tried and let it works but not like i want.
i run the page with this line of code first readfile($filesize); to read the file size
then i replace it by readfile($vd); then refrech the page.
it's run now and i can go to any time of the video but that's not i want .
i want to to run from the first time and works with the online videos links.

Requested Headers

GET /s/videos.php?h=asbiudsaudsausbdisa HTTP/1.1
Host: localhost
Connection: keep-alive
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="90", "Google Chrome";v="90"
DNT: 1
Accept-Encoding: identity;q=1, *;q=0
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36
Accept: */*
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: no-cors
Sec-Fetch-Dest: video
Referer: http://localhost/s/
Accept-Language: en
Range: bytes=0-

Response Headers

Connection: Keep-Alive
Content-Length: 125
Content-Type: text/html; charset=UTF-8
Date: Fri, 23 Apr 2021 11:01:44 GMT
Keep-Alive: timeout=5, max=100
Server: Apache/2.4.41 (Win64) OpenSSL/1.1.1c PHP/7.4.2
X-Powered-By: PHP/7.4.2
MTK
  • 3,300
  • 2
  • 33
  • 49
  • Can you share a sample of the actual headers being returned to the client? – Evert Apr 22 '21 at 20:21
  • @Evert i searched and found this question how to get benefit from it [https://stackoverflow.com/questions/37134341/web-video-bytes-range-to-time](https://stackoverflow.com/questions/37134341/web-video-bytes-range-to-time) – Eslam Alawy Apr 23 '21 at 10:35
  • @Evert i eidited the post with the headers, Take a look pleaes ♥ – Eslam Alawy Apr 23 '21 at 11:08
  • `Range: bytes=0-` means, the browser did not request any specific range to begin with, just the whole thing. Is this a request made _after_ you tried to skip to a different position in the video? – CBroe Apr 23 '21 at 11:10
  • @CBroe it don't allow me to go to any specific time – Eslam Alawy Apr 23 '21 at 11:14
  • @CBroe i tried to skip it gives me the same header – Eslam Alawy Apr 23 '21 at 11:16
  • And have you checked how this behaves, when you just request the video via the web server directly, without proxying the request through a PHP script? Does your browser send range requests then? – CBroe Apr 23 '21 at 11:17
  • when i give the video url to the ` – Eslam Alawy Apr 23 '21 at 11:19
  • @CBroe i let the video run and got this `GET /s/videos.php?h=asbiudsaudsausbdisa HTTP/1.1 Host: localhost Connection: keep-alive sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="90", "Google Chrome";v="90" DNT: 1 Accept-Encoding: identity;q=1, *;q=0 sec-ch-ua-mobile: ?0 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36 Accept: */* Sec-Fetch-Site: same-origin Sec-Fetch-Mode: no-cors Sec-Fetch-Dest: video Referer: http://localhost/s/ Accept-Language: en Range: bytes=4587520-` – Eslam Alawy Apr 23 '21 at 11:22
  • `Range: bytes=4587520-` – so the browser _is_ requesting the range from position 4587520 to the end here. Now check if your script responds to that accordingly. If it doesn’t, then debug it and try to find out why. – CBroe Apr 23 '21 at 11:29
  • @CBroe it back to `GET /s/videos.php?h=asbiudsaudsausbdisa HTTP/1.1 Host: localhost Connection: keep-alive sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="90", "Google Chrome";v="90" DNT: 1 Accept-Encoding: identity;q=1, *;q=0 sec-ch-ua-mobile: ?0 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36 Accept: */* Sec-Fetch-Site: same-origin Sec-Fetch-Mode: no-cors Sec-Fetch-Dest: video Referer: http://localhost/s/ Accept-Language: en Range: bytes=0- ` – Eslam Alawy Apr 23 '21 at 11:35
  • @CBroe but in last case i found 2 files of same header request so the second one gives me the last result .. but now that was 1 file only and gives me this result – Eslam Alawy Apr 23 '21 at 11:36
  • I don’t understand what you are trying to say with that last comment. – CBroe Apr 23 '21 at 11:42
  • @CBroe i mean on DevTools of google chrome i found 2 records with `videos.php?h=asbiudsaudsausbdisa` so that's what i mean – Eslam Alawy Apr 23 '21 at 11:45
  • After you tried skipping? Or is the first one just the request that was made when you initially started to play the video, before you tried to skip somewhere else? – CBroe Apr 23 '21 at 11:50
  • @CBroe i tried but nothing happen still `Range: bytes=0-` after skipping or before skipping – Eslam Alawy Apr 23 '21 at 11:54
  • Then was what `Range: bytes=4587520-`, which you showed before? How did you manage to get _that_? – CBroe Apr 23 '21 at 12:01
  • @CBroe oh i found how i got this result. first there is green bar when i refrech the page in Devtools so if i click on the large grean bar it gives me `range 0` when i run the video there is another green bar but thiner than {the big at the first} and gives me `range 4587520` – Eslam Alawy Apr 23 '21 at 12:09
  • Your response headers are clearly missing `Accept-Ranges`, `Content-Range`, etc – Evert Apr 23 '21 at 18:40
  • @Evert what we can do to fix it – Eslam Alawy Apr 24 '21 at 01:57

1 Answers1

1

I have spended half day to solve something like that. All the answers I've found tried to manually calculate

$_SERVER['HTTP_RANGE'] 
header('HTTP/1.1 206 Partial Content');
header('Content-Range: ...); //etc ...

as in the example of this question

At least in 2022 with php 8.0 and Chrome v 101 All this is not necessary (and also does not work)

The problem:

If you put the real path/file ex: <source src="/video_folder/file_name.mp4"> everything works correctly (we are talking about the seek bar) forwards and backwards

but

If you handle the videos through a script (as in this question) <source src="/videos.php?my_variable=file_name.mp4"> the seek bar forwards and backwards never working (at least in Chrome)

Solution: videos.php script must be like this:

<?php
  $vids = ['asbiudsaudsausbdisa' => 'video.mp4'];

  $file_path = "/absolute_path/video_folder";    
  $filehash = $_GET['h'];
  $file_name = $vids[$filehash];
  $file = $file_path."/".$file_name;
  $filesize = filesize($file);

    
  header('Content-Length: ' . $filesize);
  header('Content-Type: video/mp4');
  header('Accept-Ranges: bytes');
  readfile($file);
?>
MTK
  • 3,300
  • 2
  • 33
  • 49