PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 4.0.4
Tutor LMS – eLearning and online course solution v4.0.4
4.0.4 4.0.3 4.0.2 4.0.1 4.0.0 3.9.15 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 month ago Admin.php 2 weeks ago Ajax.php 1 month ago Announcements.php 1 month ago Assets.php 1 week ago Backend_Page_Trait.php 1 year ago BaseController.php 1 year ago Config.php 1 month ago Container.php 1 year ago Course.php 1 month ago Course_Embed.php 3 years ago Course_Filter.php 1 month ago Course_List.php 1 month ago Course_Settings_Tabs.php 1 month ago Course_Widget.php 1 year ago Custom_Validation.php 1 month ago Dashboard.php 1 month ago Earnings.php 10 months ago FormHandler.php 1 month ago Frontend.php 1 month ago Gutenberg.php 1 year ago Icon.php 2 weeks ago Input.php 1 month ago Instructor.php 1 month ago Instructors_List.php 1 month ago Lesson.php 1 month ago Options_V2.php 1 month ago Permalink.php 1 month ago Post_types.php 1 month ago Private_Course_Access.php 1 month ago Q_And_A.php 1 month ago Question_Answers_List.php 1 year ago Quiz.php 2 weeks ago QuizBuilder.php 1 month ago Quiz_Attempts_List.php 4 weeks ago RestAPI.php 4 weeks ago Reviews.php 1 month ago Rewrite_Rules.php 2 years ago SampleCourse.php 1 month ago Shortcode.php 1 month ago Singleton.php 1 year ago Student.php 1 month ago Students_List.php 1 year ago Taxonomies.php 1 year ago Template.php 1 month ago Theme_Compatibility.php 3 years ago Tools.php 1 year ago Tools_V2.php 2 months ago Tutor.php 1 month ago TutorEDD.php 1 month ago Tutor_Base.php 2 years ago Tutor_Setup.php 1 month ago Upgrader.php 1 month ago User.php 1 week ago UserPreference.php 1 month ago Utils.php 2 weeks ago Video_Stream.php 3 years ago WhatsNew.php 4 weeks ago Withdraw.php 1 month ago Withdraw_Requests_List.php 1 year ago WooCommerce.php 1 month 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