API
2 years ago
Blocks
5 years ago
License
5 years ago
AdminNotice.php
5 years ago
AdminNotices.php
4 years ago
AjaxActions.php
2 years ago
Blocks.php
4 years ago
Compatibility.php
4 years ago
Menu.php
2 years ago
Migrations.php
5 years ago
Player.php
2 years ago
ProCompatibility.php
2 years ago
ReusableVideos.php
2 years ago
Scripts.php
2 years ago
Settings.php
4 years ago
Shortcodes.php
2 years ago
Streamer.php
4 years ago
Translation.php
2 years ago
VideoPostType.php
2 years ago
Streamer.php
130 lines
| 1 | <?php |
| 2 | |
| 3 | namespace PrestoPlayer\Services; |
| 4 | |
| 5 | class Streamer |
| 6 | { |
| 7 | private $path = ''; |
| 8 | private $stream = ''; |
| 9 | private $buffer = 0; |
| 10 | private $start = -1; |
| 11 | private $end = -1; |
| 12 | private $size = 0; |
| 13 | private $type = ''; |
| 14 | |
| 15 | function __construct($file_path, $file_type, $buffer = 102400) |
| 16 | { |
| 17 | $this->path = $file_path; |
| 18 | $this->type = $file_type; |
| 19 | $this->buffer = $buffer; |
| 20 | } |
| 21 | |
| 22 | /** |
| 23 | * Start streaming video content |
| 24 | */ |
| 25 | function start() |
| 26 | { |
| 27 | $this->open(); |
| 28 | $this->set_header(); |
| 29 | $this->stream(); |
| 30 | $this->end(); |
| 31 | } |
| 32 | |
| 33 | /** |
| 34 | * Open stream |
| 35 | */ |
| 36 | private function open() |
| 37 | { |
| 38 | |
| 39 | $this->stream = fopen($this->path, 'rb'); |
| 40 | |
| 41 | if (!$this->stream) { |
| 42 | die('Could not open stream for reading'); |
| 43 | } |
| 44 | } |
| 45 | |
| 46 | /** |
| 47 | * Set proper header to serve the video content |
| 48 | */ |
| 49 | private function set_header() |
| 50 | { |
| 51 | |
| 52 | $this->start = 0; |
| 53 | $this->size = filesize($this->path); |
| 54 | $this->end = $this->size - 1; |
| 55 | |
| 56 | ob_get_clean(); |
| 57 | header('Content-Type: '. $this->type); |
| 58 | header('Cache-Control: max-age=2592000, public'); |
| 59 | header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 2592000) . ' GMT'); |
| 60 | header('Last-Modified: ' . gmdate('D, d M Y H:i:s', @filemtime($this->path)) . ' GMT'); |
| 61 | header('Accept-Ranges: 0-' . $this->end); |
| 62 | |
| 63 | if (isset($_SERVER['HTTP_RANGE'])) { |
| 64 | |
| 65 | $c_start = $this->start; |
| 66 | $c_end = $this->end; |
| 67 | |
| 68 | list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2); |
| 69 | if (strpos($range, ',') !== false) { |
| 70 | header('HTTP/1.1 416 Requested Range Not Satisfiable'); |
| 71 | header("Content-Range: bytes $this->start-$this->end/$this->size"); |
| 72 | exit; |
| 73 | } |
| 74 | if ('-' == $range) { |
| 75 | $c_start = $this->size - substr($range, 1); |
| 76 | } else { |
| 77 | $range = explode('-', $range); |
| 78 | $c_start = $range[0]; |
| 79 | $c_end = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $c_end; |
| 80 | } |
| 81 | $c_end = ($c_end > $this->end) ? $this->end : $c_end; |
| 82 | if ($c_start > $c_end || $c_start > $this->size - 1 || $c_end >= $this->size) { |
| 83 | header('HTTP/1.1 416 Requested Range Not Satisfiable'); |
| 84 | header("Content-Range: bytes $this->start-$this->end/$this->size"); |
| 85 | exit; |
| 86 | } |
| 87 | $this->start = $c_start; |
| 88 | $this->end = $c_end; |
| 89 | $length = $this->end - $this->start + 1; |
| 90 | fseek($this->stream, $this->start); |
| 91 | header('HTTP/1.1 206 Partial Content'); |
| 92 | header('Content-Length: ' . $length); |
| 93 | header("Content-Range: bytes $this->start-$this->end/" . $this->size); |
| 94 | } else { |
| 95 | |
| 96 | header('Content-Length: ' . $this->size); |
| 97 | } |
| 98 | } |
| 99 | |
| 100 | /** |
| 101 | * perform the streaming of calculated range |
| 102 | */ |
| 103 | private function stream() |
| 104 | { |
| 105 | |
| 106 | $i = $this->start; |
| 107 | set_time_limit(0); |
| 108 | |
| 109 | while (!feof($this->stream) && $i <= $this->end) { |
| 110 | $bytes_to_read = $this->buffer; |
| 111 | if (($i + $bytes_to_read) > $this->end) { |
| 112 | $bytes_to_read = $this->end - $i + 1; |
| 113 | } |
| 114 | $data = fread($this->stream, $bytes_to_read); |
| 115 | echo $data; |
| 116 | flush(); |
| 117 | $i += $bytes_to_read; |
| 118 | } |
| 119 | } |
| 120 | |
| 121 | /** |
| 122 | * close curretly opened stream |
| 123 | */ |
| 124 | private function end() |
| 125 | { |
| 126 | fclose($this->stream); |
| 127 | exit; |
| 128 | } |
| 129 | } |
| 130 |