import 'package:path/path.dart' as p; import '../../core/playlist.dart'; import '../../core/vfs.dart'; import '../../l10n/tr.dart'; import '../../services/app_shell.dart'; import '../../services/storage_service.dart'; import '../settings.dart'; /// 재생 준비. 약속: [prepare] 는 동영상 · 음악만 골라, 확장자에 외부 프로그램이 지정되어 있으면 그것으로 열고 null, /// 아니면 내장 플레이어용 (목록, 시작 위치) 을 준다. 하나면 같은 폴더로 재생 목록 ([PlaybackSettings.playlistMode]). class PlaybackPrep { final StorageService storage; final AppShell shell; final void Function(String msg) log; PlaybackPrep({required this.storage, required this.shell, required this.log}); /// [keepOrder]: 여러 개를 줄 때 이름순으로 다시 정렬하지 않고 준 순서대로 재생 /// [internal]: 외부 프로그램 설정과 상관없이 내장 플레이어로 (파일 탐색기의 "내장 플레이어로 재생") /// [external]: 외부 프로그램으로 열 때 (화면이 WebDAV 로그인 안내 등을 한다 - 55). 없으면 바로 연다 Future<(List, int)?> prepare(List files, PlaybackSettings settings, {bool keepOrder = false, bool internal = false, Future Function(String program, List videos)? external}) async { // 29: 음악도 내장 플레이어로 (탐색기 메뉴의 "내장 플레이어로 재생") final videos = files.where((f) => isVideoFile(f) || isAudioFile(f)).toList(); if (videos.isEmpty) return null; final ext = p.extension(videos.first).replaceFirst('.', '').toLowerCase(); final program = settings.externalPlayers[ext]; if (!internal && program != null && program.isNotEmpty) { // WebDAV 는 스트리밍 주소로 넘긴다 (아이디 · 비밀번호는 넣지 않음 - 55) if (external != null) { await external(program, videos); } else { await shell.openExternal(program, videos.map(vPlayable).toList()); } log(trf('외부 프로그램으로 재생: {0} ← {1}개', [program == 'system' ? tr('기본 연결 프로그램') : p.basename(program), videos.length])); return null; } if (videos.length > 1) { if (!keepOrder) videos.sort((a, b) => naturalCompare(p.basename(a), p.basename(b))); return (videos, 0); } final siblings = isDav(videos.first) ? [for (final e in await vList(vDirname(videos.first))) if (!e.isDir) e.path] : await storage.listFiles(p.dirname(videos.first)); return buildPlaylist(videos.first, siblings, settings.playlistMode); } }