JJ_MKVMaker/test/support/batch_doubles.dart

103 lines
3.7 KiB
Dart

/// MKV 묶음 · 다운로드 시험의 대역 (batch_test · batch_ui_test 가 같이 쓴다): 멈춰 두는 FFmpeg · 음성인식 · 번역 · 다운로드 엔진
library;
import 'dart:async';
import 'dart:io';
import 'package:jj_mkvmaker/app/app_controller.dart';
import 'package:jj_mkvmaker/core/download_detect.dart';
import 'package:jj_mkvmaker/core/models.dart';
import 'package:jj_mkvmaker/core/srt.dart';
import 'package:jj_mkvmaker/platform/windows/desktop_storage_service.dart';
import 'package:jj_mkvmaker/platform/windows/process_media_tool.dart';
import 'package:jj_mkvmaker/services/ai_services.dart';
import 'package:jj_mkvmaker/services/downloader.dart';
import 'package:jj_mkvmaker/services/media_tool.dart';
import 'package:jj_mkvmaker/services/platform_services.dart';
import 'package:path/path.dart' as p;
class TestRecognizer implements SpeechRecognizer {
@override
void cancel() {}
final heard = <String>[];
@override
Future<List<Cue>> transcribe(String wavPath,
{required String modelPath, String language = 'auto', AiProgress? onProgress}) async {
heard.add(p.basename(wavPath));
return [Cue(const Duration(seconds: 1), const Duration(seconds: 2), 'Hello everyone, this is a test.')];
}
}
/// 240: 취소될 때까지 끝나지 않는 FFmpeg (여럿이 동시에 도는 상태를 만든다)
class HoldTool implements MediaTool {
final runs = <Object?, Completer<void>>{};
@override
Future<String?> version() async => 'ffmpeg test';
@override
Future<Set<String>> encoders() async => {'libx264'};
@override
Future<MediaInfo> probe(String path) async => const MediaInfo(duration: Duration(seconds: 1));
@override
Future<void> runFfmpeg(List<String> args, {Duration? duration, ProgressCallback? onProgress, Object? tag}) async {
final c = runs[tag] = Completer<void>();
try {
await c.future;
} finally {
runs.remove(tag);
}
}
void _stop(Completer<void>? c) {
if (c != null && !c.isCompleted) c.completeError(MediaToolException('사용자가 취소했습니다.'));
}
@override
void cancel() => runs.values.toList().forEach(_stop);
@override
void cancelTagged(Object tag) => _stop(runs[tag]);
}
class TestTranslator implements Translator {
@override
Future<void> load(String modelDir) async {}
@override
Future<List<String>> translate(List<String> lines,
{required String source, required String target, AiProgress? onProgress}) async =>
[for (final l in lines) '[$target] $l'];
@override
void cancel() {}
@override
Future<void> dispose() async {}
}
class TestDownloadBackend implements DownloadBackend {
@override
DownloadKind get kind => DownloadKind.video;
@override
Future<(String, List<PlaylistEntry>)?> expandPlaylist(String url) async => null;
@override
Future<void> start(DownloadTask t, void Function() changed) async => t.state = DownloadState.downloading;
@override
Future<void> pause(DownloadTask t) async {}
@override
Future<void> cancel(DownloadTask t) async {}
@override
Future<void> shutdown() async {}
}
/// 262: [HoldTool] 과 같지만, 끝내면 (결과 이름으로 바꿀) 임시 출력 파일을 쓴다
class EndTool extends HoldTool {
final args = <Object?, List<String>>{};
@override
Future<void> runFfmpeg(List<String> a, {Duration? duration, ProgressCallback? onProgress, Object? tag}) async {
args[tag] = a;
await super.runFfmpeg(a, duration: duration, onProgress: onProgress, tag: tag);
File(a.last).writeAsStringSync('NEW');
}
/// [tag] 의 FFmpeg 를 성공으로 끝낸다
void finish(Object tag) => runs[tag]!.complete();
}
AppController plainController() =>
AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));