mirror of
https://github.com/R0m1k3/xtremflow.git
synced 2026-10-22 06:28:04 +02:00
feat: introduce core server with API, media streaming, Xtream proxy, and player UI
This commit is contained in:
1 parent
7372f51b19
commit
b244f1f807
2 files changed
+15
-5
No files matched your search
+13
-3
@@ -279,10 +279,17 @@ Future<Response> _streamVideoFile(Uri targetUrl, String? rangeHeader) async {
|
|||||||
|
|
||||||
// Forward the Range header for seeking support
|
// Forward the Range header for seeking support
|
||||||
if (rangeHeader != null && rangeHeader.isNotEmpty) {
|
if (rangeHeader != null && rangeHeader.isNotEmpty) {
|
||||||
req.headers.set('Range', rangeHeader);
|
// Ensure we request bytes
|
||||||
|
if (!rangeHeader.startsWith('bytes=')) {
|
||||||
|
rangeHeader = 'bytes=$rangeHeader';
|
||||||
|
}
|
||||||
|
req.headers.set(HttpHeaders.rangeHeader, rangeHeader);
|
||||||
print('Video streaming with Range: $rangeHeader');
|
print('Video streaming with Range: $rangeHeader');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Disable auto-decompression to strictly proxy the stream
|
||||||
|
client.autoUncompress = false;
|
||||||
|
|
||||||
final response = await req.close();
|
final response = await req.close();
|
||||||
|
|
||||||
// Get content type from response
|
// Get content type from response
|
||||||
@@ -303,11 +310,14 @@ Future<Response> _streamVideoFile(Uri targetUrl, String? rangeHeader) async {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add Content-Range if this is a partial response (206)
|
// Add Content-Range if this is a partial response (206)
|
||||||
final contentRange = response.headers.value('content-range');
|
final contentRange = response.headers.value(HttpHeaders.contentRangeHeader);
|
||||||
if (contentRange != null) {
|
if (contentRange != null) {
|
||||||
responseHeaders['content-range'] = contentRange;
|
responseHeaders[HttpHeaders.contentRangeHeader] = contentRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Propagate Accept-Ranges
|
||||||
|
responseHeaders[HttpHeaders.acceptRangesHeader] = 'bytes';
|
||||||
|
|
||||||
// Return appropriate status code (200 for full, 206 for partial)
|
// Return appropriate status code (200 for full, 206 for partial)
|
||||||
return Response(
|
return Response(
|
||||||
response.statusCode,
|
response.statusCode,
|
||||||
|
|||||||
@@ -735,11 +735,11 @@ class _PlayerScreenState extends ConsumerState<PlayerScreen> {
|
|||||||
// EPG Overlay
|
// EPG Overlay
|
||||||
if (widget.streamType == StreamType.live)
|
if (widget.streamType == StreamType.live)
|
||||||
Positioned(
|
Positioned(
|
||||||
bottom: 0,
|
bottom: 100, // Move up above progress bar area/OS safe area
|
||||||
left: 0,
|
left: 0,
|
||||||
right: 0,
|
right: 0,
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: const EdgeInsets.only(bottom: 20),
|
padding: const EdgeInsets.only(bottom: 8),
|
||||||
decoration: const BoxDecoration(
|
decoration: const BoxDecoration(
|
||||||
gradient: LinearGradient(
|
gradient: LinearGradient(
|
||||||
begin: Alignment.bottomCenter,
|
begin: Alignment.bottomCenter,
|
||||||
|
|||||||
Reference in new issue
Block a user