PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 3.1.0
Tutor LMS – eLearning and online course solution v3.1.0
3.9.14 3.9.13 3.9.12 3.9.11 trunk 1.0.0 1.0.0-alpha 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.2.0 1.2.1 1.2.11 1.2.12 1.2.13 1.2.20 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 1.7.6 1.7.7 1.7.8 1.7.9 1.8.0 1.8.1 1.8.10 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9.0 1.9.1 1.9.10 1.9.11 1.9.12 1.9.13 1.9.14 1.9.15 1.9.16 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.1 2.0.10 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1.0 2.1.1 2.1.10 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.3.0 2.4.0 2.5.0 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 3.0.0 3.0.1 3.0.2 3.1.0 3.2.0 3.2.1 3.2.2 3.2.3 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.7.0 3.7.1 3.7.2 3.7.3 3.7.4 3.8.0 3.8.1 3.8.2 3.8.3 3.9.0 3.9.1 3.9.10 3.9.2 3.9.3 3.9.4 3.9.5 3.9.6 3.9.7 3.9.8 3.9.9
tutor / classes / Video_Stream.php
tutor / classes Last commit date
Addons.php 1 year ago Admin.php 1 year ago Ajax.php 1 year ago Announcements.php 1 year ago Assets.php 1 year ago Backend_Page_Trait.php 1 year ago BaseController.php 1 year ago Course.php 1 year ago Course_Embed.php 3 years ago Course_Filter.php 1 year ago Course_List.php 1 year ago Course_Settings_Tabs.php 1 year ago Course_Widget.php 3 years ago Custom_Validation.php 3 years ago Dashboard.php 1 year ago Earnings.php 1 year ago FormHandler.php 2 years ago Frontend.php 1 year ago Gutenberg.php 1 year ago Input.php 1 year ago Instructor.php 1 year ago Instructors_List.php 1 year ago Lesson.php 1 year ago Options_V2.php 1 year ago Permalink.php 2 years ago Post_types.php 2 years ago Private_Course_Access.php 1 year ago Q_And_A.php 1 year ago Question_Answers_List.php 3 years ago Quiz.php 1 year ago QuizBuilder.php 1 year ago Quiz_Attempts_List.php 1 year ago RestAPI.php 2 years ago Reviews.php 3 years ago Rewrite_Rules.php 2 years ago Shortcode.php 1 year ago Singleton.php 1 year ago Student.php 1 year ago Students_List.php 3 years ago Taxonomies.php 3 years ago Template.php 1 year ago Theme_Compatibility.php 3 years ago Tools.php 3 years ago Tools_V2.php 1 year ago Tutor.php 1 year ago TutorEDD.php 1 year ago Tutor_Base.php 2 years ago Tutor_Setup.php 1 year ago Upgrader.php 1 year ago User.php 1 year ago Utils.php 1 year ago Video_Stream.php 3 years ago WhatsNew.php 2 years ago Withdraw.php 1 year ago Withdraw_Requests_List.php 1 year ago WooCommerce.php 1 year ago
Video_Stream.php
219 lines
1 <?php
2 /**
3 * Video Stream
4 *
5 * @package Tutor\VideoStream
6 * @author Themeum <support@themeum.com>
7 * @link https://themeum.com
8 * @since 1.0.0
9 */
10
11 namespace TUTOR;
12
13 if ( ! defined( 'ABSPATH' ) ) {
14 exit;
15 }
16
17
18 /**
19 * Class Video_Stream
20 *
21 * @since 1.0.0
22 */
23 class Video_Stream {
24
25 /**
26 * Path
27 *
28 * @since 1.0.0
29 *
30 * @var string
31 */
32 private $path = '';
33
34 /**
35 * Stream
36 *
37 * @since 1.0.0
38 *
39 * @var string
40 */
41 private $stream = '';
42
43 /**
44 * Buffer time
45 *
46 * @since 1.0.0
47 *
48 * @var string
49 */
50 private $buffer = 102400;
51
52 /**
53 * Start
54 *
55 * @since 1.0.0
56 *
57 * @var int
58 */
59 private $start = -1;
60
61 /**
62 * End
63 *
64 * @since 1.0.0
65 *
66 * @var int
67 */
68 private $end = -1;
69
70 /**
71 * Size
72 *
73 * @since 1.0.0
74 *
75 * @var int
76 */
77 private $size = 0;
78
79 /**
80 * Video format
81 *
82 * @since 1.0.0
83 *
84 * @var string
85 */
86 private $video_format;
87
88 /**
89 * Resolve dependencies
90 *
91 * @since 1.0.0
92 *
93 * @param string $file_path file path.
94 */
95 public function __construct( $file_path ) {
96 $this->video_format = apply_filters(
97 'tutor_video_types',
98 array(
99 'mp4' => 'video/mp4',
100 'webm' => 'video/webm',
101 'ogg' => 'video/ogg',
102 )
103 );
104 $this->path = $file_path;
105 }
106
107 /**
108 * Open stream
109 *
110 * @since 1.0.0
111 *
112 * @return void
113 */
114 private function open() {
115 $this->stream = fopen( $this->path, 'rb' );
116 if ( ! ( $this->stream ) ) {
117 die( 'Could not open stream for reading' );
118 }
119 }
120
121 /**
122 * Set proper header to serve the video content
123 *
124 * @since 1.0.0
125 *
126 * @return void
127 */
128 private function set_header() {
129 ob_get_clean();
130
131 header( 'Content-Type: ' . $this->video_format[ strtolower( pathinfo( $this->path, PATHINFO_EXTENSION ) ) ] );
132 header( 'Cache-Control: max-age=2592000, public' );
133 header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', tutor_time() + 2592000 ) . ' GMT' );
134 header( 'Last-Modified: ' . gmdate( 'D, d M Y H:i:s', @filemtime( $this->path ) ) . ' GMT' );
135 $this->start = 0;
136 $this->size = filesize( $this->path );
137 $this->end = $this->size - 1;
138 header( 'Accept-Ranges: 0-' . $this->end );
139
140 if ( isset( $_SERVER['HTTP_RANGE'] ) ) {
141 $c_end = $this->end;
142 list(, $range) = explode( '=', sanitize_text_field( wp_unslash( $_SERVER['HTTP_RANGE'] ) ), 2 );
143
144 if ( '-' == $range ) {
145 $c_start = $this->size - substr( $range, 1 );
146 } else {
147 $range = explode( '-', $range );
148 $c_start = $range[0];
149
150 $c_end = ( isset( $range[1] ) && is_numeric( $range[1] ) ) ? $range[1] : $c_end;
151 }
152 $c_end = ( $c_end > $this->end ) ? $this->end : $c_end;
153 if ( $c_start > $c_end || $c_start > $this->size - 1 || $c_end >= $this->size ) {
154 header( 'HTTP/1.1 416 Requested Range Not Satisfiable' );
155 header( "Content-Range: bytes $this->start-$this->end/$this->size" );
156 exit;
157 }
158 $this->start = $c_start;
159 $this->end = $c_end;
160 $length = $this->end - $this->start + 1;
161 header( 'HTTP/1.1 206 Partial Content' );
162 header( 'Content-Length: ' . $length );
163 header( "Content-Range: bytes $this->start-$this->end/" . $this->size );
164 header( 'Accept-Ranges: bytes' );
165 } else {
166 header( 'Content-Length: ' . $this->size );
167 }
168
169 }
170
171 /**
172 * Close currently opened stream
173 *
174 * @since 1.0.0
175 *
176 * @return void
177 */
178 private function end() {
179 fclose( $this->stream );
180 exit;
181 }
182
183 /**
184 * Perform the streaming of calculated range
185 *
186 * @since 1.0.0
187 *
188 * @return void
189 */
190 private function stream() {
191 $i = $this->start;
192 set_time_limit( 0 );
193 while ( ! feof( $this->stream ) && $i <= $this->end ) {
194 $bytes_to_read = $this->buffer;
195 if ( ( $i + $bytes_to_read ) > $this->end ) {
196 $bytes_to_read = $this->end - $i + 1;
197 }
198 $data = @stream_get_contents( $this->stream, $bytes_to_read, $i );
199 echo wp_kses_post( $data );
200 flush();
201 $i += $bytes_to_read;
202 }
203 }
204
205 /**
206 * Start streaming tutor video content
207 *
208 * @since 1.0.0
209 *
210 * @return void
211 */
212 public function start() {
213 $this->open();
214 $this->set_header();
215 $this->stream();
216 $this->end();
217 }
218 }
219