76 lines
3.0 KiB
Dart
76 lines
3.0 KiB
Dart
import 'dart:convert';
|
|
import 'dart:io';
|
|
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:jj_mkvmaker/core/charset_detector.dart';
|
|
import 'package:jj_mkvmaker/core/languages.dart';
|
|
import 'package:jj_mkvmaker/core/mkv_command_builder.dart';
|
|
import 'package:jj_mkvmaker/core/models.dart';
|
|
import 'package:jj_mkvmaker/core/output_paths.dart';
|
|
import 'package:jj_mkvmaker/core/subtitle_detector.dart';
|
|
import 'package:jj_mkvmaker/platform/windows/process_media_tool.dart';
|
|
import 'package:path/path.dart' as p;
|
|
|
|
/// 실제 FFmpeg 로 MKV 를 만들어 확인 (FFmpeg 가 없으면 건너뜀)
|
|
void main() {
|
|
final tool = ProcessMediaTool('ffmpeg', 'ffprobe');
|
|
late Directory dir;
|
|
|
|
setUp(() => dir = Directory.systemTemp.createTempSync('jj_mux_'));
|
|
tearDown(() => dir.deleteSync(recursive: true));
|
|
|
|
test('mp4 + 같은 폴더 자막(UTF-8, CP949) → jj_mkv/영화.mkv', () async {
|
|
if (await tool.version() == null) {
|
|
markTestSkipped('FFmpeg 없음');
|
|
return;
|
|
}
|
|
final video = p.join(dir.path, '영화 테스트.mp4');
|
|
await tool.runFfmpeg([
|
|
'-hide_banner', '-y', '-f', 'lavfi', '-i', 'testsrc=size=320x240:rate=10',
|
|
'-f', 'lavfi', '-i', 'sine=frequency=440', '-t', '3',
|
|
'-c:v', 'libx264', '-c:a', 'aac', '-shortest', video,
|
|
]);
|
|
|
|
// UTF-8 영어 자막
|
|
File(p.join(dir.path, '영화 테스트.en.srt'))
|
|
.writeAsStringSync('1\n00:00:00,500 --> 00:00:02,000\nHello\n');
|
|
// CP949 한국어 자막: "안녕"
|
|
File(p.join(dir.path, '영화 테스트_ko.srt')).writeAsBytesSync([
|
|
...ascii.encode('1\r\n00:00:00,500 --> 00:00:02,000\r\n'),
|
|
0xBE, 0xC8, 0xB3, 0xE7, 0x0D, 0x0A,
|
|
]);
|
|
|
|
final v = VideoItem(video)..info = await tool.probe(video);
|
|
final files = dir.listSync().map((e) => e.path);
|
|
for (final d in findSiblingSubtitles(video, files)) {
|
|
v.subtitles.add(SubtitleEntry.external(
|
|
path: d.path,
|
|
language: d.language,
|
|
charset: detectCharset(File(d.path).readAsBytesSync()),
|
|
));
|
|
}
|
|
expect(v.subtitles.map((s) => s.charset), containsAll(['UTF-8', 'CP949']));
|
|
|
|
final out = outputMkvPath(video);
|
|
await Directory(outputDirFor(video)).create();
|
|
double last = 0;
|
|
await tool.runFfmpeg(buildMuxArgs(v, out),
|
|
duration: v.info!.duration, onProgress: (x) => last = x);
|
|
expect(last, 1.0);
|
|
|
|
final info = await tool.probe(out);
|
|
final subs = info.ofType('subtitle').toList();
|
|
expect(subs.map((s) => s.language), containsAll(['eng', 'kor']));
|
|
expect(subs.firstWhere((s) => s.language == 'kor').isDefault, isTrue);
|
|
expect(info.ofType('video'), hasLength(1));
|
|
expect(info.ofType('audio'), hasLength(1));
|
|
|
|
// CP949 자막이 UTF-8 로 올바르게 변환되었는지 확인
|
|
final koIndex = subs.firstWhere((s) => s.language == 'kor').index;
|
|
final srt = p.join(dir.path, 'check.srt');
|
|
await tool.runFfmpeg(['-y', '-i', out, '-map', '0:$koIndex', srt]);
|
|
expect(File(srt).readAsStringSync(), contains('안녕'));
|
|
expect(languageOf('kor').code, 'ko');
|
|
}, timeout: const Timeout(Duration(minutes: 2)));
|
|
}
|