PluginProbe
Tutor LMS – eLearning and online course solution / 2.0.1
Tutor LMS – eLearning and online course solution v2.0.1
4.0.7 4.0.6 4.0.5 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 All 191 releases
tutor / classes / Video_Stream.php

Video_Stream.php in Tutor LMS – eLearning and online course solution 2.0.1, at classes/Video_Stream.php

140 lines 3.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Created by PhpStorm.
4 * User: themeum
5 * Date: 24/9/18
6 * Time: 4:03 PM
7 */
8
9 namespace TUTOR;
10
11 if ( ! defined( 'ABSPATH' ) ) {
12 exit;
13 }
14
15
16 /**
17 * Class Video_Stream
18 *
19 * @package TUTOR
20 *
21 * TUTOR Video Stream Class
22 * @since v.1.0.0
23 */
24
25 class Video_Stream {
26
27 private $path = '';
28 private $stream = '';
29 private $buffer = 102400;
30 private $start = -1;
31 private $end = -1;
32 private $size = 0;
33
34 private $videoFormats;
35
36 function __construct( $filePath ) {
37 $this->videoFormats = apply_filters(
38 'tutor_video_types',
39 array(
40 'mp4' => 'video/mp4',
41 'webm' => 'video/webm',
42 'ogg' => 'video/ogg',
43 )
44 );
45 $this->path = $filePath;
46 }
47
48 /**
49 * Open stream
50 */
51 private function open() {
52 if ( ! ( $this->stream = fopen( $this->path, 'rb' ) ) ) {
53 die( 'Could not open stream for reading' );
54 }
55 }
56
57 /**
58 * Set proper header to serve the video content
59 */
60 private function setHeader() {
61 ob_get_clean();
62
63 header( 'Content-Type: ' . $this->videoFormats[ strtolower( pathinfo( $this->path, PATHINFO_EXTENSION ) ) ] );
64 header( 'Cache-Control: max-age=2592000, public' );
65 header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', tutor_time() + 2592000 ) . ' GMT' );
66 header( 'Last-Modified: ' . gmdate( 'D, d M Y H:i:s', @filemtime( $this->path ) ) . ' GMT' );
67 $this->start = 0;
68 $this->size = filesize( $this->path );
69 $this->end = $this->size - 1;
70 header( 'Accept-Ranges: 0-' . $this->end );
71
72 if ( isset( $_SERVER['HTTP_RANGE'] ) ) {
73 $c_end = $this->end;
74 list(, $range) = explode( '=', $_SERVER['HTTP_RANGE'], 2 );
75
76 if ( $range == '-' ) {
77 $c_start = $this->size - substr( $range, 1 );
78 } else {
79 $range = explode( '-', $range );
80 $c_start = $range[0];
81
82 $c_end = ( isset( $range[1] ) && is_numeric( $range[1] ) ) ? $range[1] : $c_end;
83 }
84 $c_end = ( $c_end > $this->end ) ? $this->end : $c_end;
85 if ( $c_start > $c_end || $c_start > $this->size - 1 || $c_end >= $this->size ) {
86 header( 'HTTP/1.1 416 Requested Range Not Satisfiable' );
87 header( "Content-Range: bytes $this->start-$this->end/$this->size" );
88 exit;
89 }
90 $this->start = $c_start;
91 $this->end = $c_end;
92 $length = $this->end - $this->start + 1;
93 header( 'HTTP/1.1 206 Partial Content' );
94 header( 'Content-Length: ' . $length );
95 header( "Content-Range: bytes $this->start-$this->end/" . $this->size );
96 header( 'Accept-Ranges: bytes' );
97 } else {
98 header( 'Content-Length: ' . $this->size );
99 }
100
101 }
102
103 /**
104 * close currently opened stream
105 */
106 private function end() {
107 fclose( $this->stream );
108 exit;
109 }
110
111 /**
112 * perform the streaming of calculated range
113 */
114 private function stream() {
115 $i = $this->start;
116 set_time_limit( 0 );
117 while ( ! feof( $this->stream ) && $i <= $this->end ) {
118 $bytesToRead = $this->buffer;
119 if ( ( $i + $bytesToRead ) > $this->end ) {
120 $bytesToRead = $this->end - $i + 1;
121 }
122 // $data = fread($this->stream, $bytesToRead);
123 $data = @stream_get_contents( $this->stream, $bytesToRead, $i );
124 echo $data;
125 flush();
126 $i += $bytesToRead;
127 }
128 }
129
130 /**
131 * Start streaming tutor video content
132 */
133 function start() {
134 $this->open();
135 $this->setHeader();
136 $this->stream();
137 $this->end();
138 }
139 }
140