5
5
use App \Models \Channel ;
6
6
use App \Settings \GeneralSettings ;
7
7
use Illuminate \Http \Request ;
8
+ use Illuminate \Support \Facades \Storage ;
8
9
use Mockery \Exception ;
9
10
use Symfony \Component \HttpFoundation \BinaryFileResponse ;
10
11
use Symfony \Component \HttpFoundation \StreamedResponse ;
@@ -21,6 +22,11 @@ class ChannelStreamController extends Controller
21
22
*/
22
23
public function __invoke (Request $ request , $ id )
23
24
{
25
+ // Prevent timeouts
26
+ ini_set ('max_execution_time ' , 0 );
27
+ ini_set ('output_buffering ' , 'off ' );
28
+ ini_set ('implicit_flush ' , 1 );
29
+
24
30
// Find the channel by ID, else throw a 404
25
31
$ channel = Channel::findOrFail (base64_decode ($ id ));
26
32
@@ -38,40 +44,44 @@ public function __invoke(Request $request, $id)
38
44
39
45
// Stream the content directly from FFmpeg
40
46
return new StreamedResponse (function () use ($ streamUrls , $ enabledDebug ) {
47
+ if (ob_get_level () > 0 ) {
48
+ ob_end_clean ();
49
+ while (@ob_end_flush ());
50
+ }
51
+ ini_set ('zlib.output_compression ' , 0 );
52
+
41
53
foreach ($ streamUrls as $ streamUrl ) {
42
- // Try streaming from this URL
43
- $ cmd = "ffmpeg -re -i \"$ streamUrl \" -c copy -f mpegts pipe:1 " ;
44
- if (!$ enabledDebug ) {
54
+ $ cmd = "ffmpeg -re -i \"$ streamUrl \" -c copy -f mpegts pipe:1 -reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5 -timeout 100000000 -http_persistent 1 " ;
55
+ if (config ('dev.ffmpeg.debug ' )) {
56
+ $ cmd .= " 2> " . storage_path ('logs/ ' . config ('dev.ffmpeg.file ' ));
57
+ } else if (!$ enabledDebug ) {
45
58
$ cmd .= " -hide_banner -nostats -loglevel quiet 2>/dev/null " ;
46
59
}
47
60
$ process = popen ($ cmd , 'r ' );
48
61
49
62
if ($ process ) {
50
63
while (!feof ($ process )) {
51
64
if (connection_aborted ()) {
52
- pclose ($ process ); // Attempt to close FFmpeg connection immediately
65
+ pclose ($ process );
53
66
return ;
54
67
}
55
- $ data = fread ($ process , 4096 );
68
+ $ data = fread ($ process , 8192 ); // Increased from 4096 to 8192
56
69
if ($ data === false ) {
57
- break ; // Stop if no data
70
+ break ;
58
71
}
59
72
echo $ data ;
60
73
flush ();
61
74
}
62
-
63
75
pclose ($ process );
64
- return ; // Exit if stream works
76
+ return ;
65
77
}
66
78
}
67
-
68
- // If all streams fail
69
79
echo "Error: No available streams. " ;
70
80
}, 200 , [
71
81
'Content-Type ' => 'video/mp2t ' ,
72
- 'Cache-Control ' => 'no-cache, must-revalidate ' ,
73
- 'Pragma ' => 'no-cache ' ,
74
- 'Expires ' => '0 ' ,
82
+ 'Connection ' => 'keep-alive ' ,
83
+ 'Cache-Control ' => 'no-store, no-transform ' ,
84
+ 'X-Accel-Buffering ' => 'no ' , // Prevents Nginx from buffering
75
85
]);
76
86
}
77
87
0 commit comments