import 'dart:convert'; import 'package:cinema/common/video_downloader.dart'; import 'package:injectable/injectable.dart'; import 'package:shelf/shelf.dart'; import 'package:shelf_router/shelf_router.dart'; part 'video.service.g.dart'; @injectable class VideoService { final VideoDownloader _videoDownloader; VideoService(this._videoDownloader); @Route.get('/') Future downloadVideo(Request request, String videoId) async { // Validate video ID (YouTube IDs are 11 characters, alphanumeric with - and _) if (!RegExp(r'^[a-zA-Z0-9_-]{11}$').hasMatch(videoId)) { return Response( 400, body: jsonEncode({'error': 'Invalid YouTube video ID'}), headers: {'Content-Type': 'application/json'}, ); } // Check if already cached if (await _videoDownloader.isCached(videoId)) { return Response.ok( jsonEncode({ 'status': 'cached', 'videoId': videoId, 'path': '${VideoDownloader.cacheDir}/$videoId/video.mp4', }), headers: {'Content-Type': 'application/json'}, ); } // Download and resize final path = await _videoDownloader.downloadAndResize(videoId); if (path == null) { return Response( 500, body: jsonEncode({ 'error': 'Failed to download or resize video', 'videoId': videoId, }), headers: {'Content-Type': 'application/json'}, ); } return Response.ok( jsonEncode({ 'status': 'downloaded', 'videoId': videoId, 'path': path, 'size': '${VideoDownloader.maxWidth}x${VideoDownloader.maxHeight} (max)', }), headers: {'Content-Type': 'application/json'}, ); } @Route.get('/') Future listVideos(Request request) async { final videos = await _videoDownloader.getCachedVideos(); return Response.ok( jsonEncode({'videos': videos}), headers: {'Content-Type': 'application/json'}, ); } Router get router => _$VideoServiceRouter(this); }