feat: Introduce backend server with live TV proxy, VOD HLS transcoding, and IPTV streaming settings UI.

This commit is contained in:
Michael committed 2025-12-15 16:49:48 +01:00
1 parent f290f5a7fc
commit 3dc9a8def2
8 files changed
+32 -43

No files matched your search

+11 -5
View File
@@ -34,13 +34,19 @@ PlaylistConfig? _getCurrentPlaylist(Request request) {
Handler createLiveStreamHandler(Future<PlaylistConfig?> Function(Request) getPlaylist) {
final router = Router();
// Route: /api/live/{streamId}.ts
router.get('/<streamId>.ts', (Request request, String streamId) async {
final playlist = await getPlaylist(request);
if (playlist == null) {
return Response.internalServerError(body: 'No playlist configured');
// Route: /api/live/{streamId} (Catch all pattern to debug)
router.get('/<streamId|.*>', (Request request, String streamId) async {
print('[Live] Incoming request for streamId: $streamId');
// Remove .ts extension if present
if (streamId.endsWith('.ts')) {
streamId = streamId.substring(0, streamId.length - 3);
}
final playlist = await getPlaylist(request);
// ... existing logic ...
final targetUrl = Uri.parse('${playlist.dns}/live/${playlist.username}/${playlist.password}/$streamId.ts');
print('[Live] Proxying: $targetUrl');
+2
View File
@@ -15,3 +15,5 @@ dependencies:
sqlite3: ^2.4.0
crypto: ^3.0.3
uuid: ^4.3.3
hive: ^2.2.3
equatable: ^2.0.5
+9 -20
View File
@@ -10,7 +10,7 @@ import 'package:args/args.dart';
import 'database/database.dart';
import 'models/user.dart';
import 'models/playlist.dart';
import 'package:xtremflow/core/models/playlist_config.dart';
import '../lib/core/models/playlist_config.dart';
import 'api/auth_handler.dart';
import 'api/users_handler.dart';
import 'api/playlists_handler.dart';
@@ -153,12 +153,16 @@ void main(List<String> args) async {
return null;
}
// Create Streaming Router (Mount handlers on correct paths)
final streamingRouter = Router()
..mount('/api/live', createLiveStreamHandler(_getPlaylist))
..mount('/api/vod', createVodStreamHandler(_getPlaylist));
// Main handler with API proxy and NEW Streaming Handlers
final handler = Cascade()
.add(_createApiHandler(apiRouter))
.add(apiRouter.call) /* Standard API endpoints */
.add(_createXtreamProxyHandler()) /* Keep for general API calls */
.add(createLiveStreamHandler(_getPlaylist))
.add(createVodStreamHandler(_getPlaylist))
.add(streamingRouter.call) /* Streaming endpoints */
.add(staticHandler)
.handler;
@@ -190,22 +194,7 @@ void main(List<String> args) async {
});
}
/// Create API handler
Handler _createApiHandler(Router apiRouter) {
return (Request request) async {
final path = request.url.path;
// Only handle /api/* requests (excluding special handlers)
if (path.startsWith('api/') &&
!path.startsWith('api/xtream/') &&
!path.startsWith('api/live/') &&
!path.startsWith('api/vod/')) {
return apiRouter(request);
}
return Response.notFound('Not found');
};
}
/// CORS middleware to allow cross-origin requests
Middleware _corsMiddleware() {