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