이동: 만든 결과물 (jj_mkv 의 MKV · 자막) 도 이동 폴더의 jj_mkv 로 함께
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>main v2026.10.04_002
parent
b466bff15f
commit
480209b45d
|
|
@ -3,6 +3,7 @@
|
|||
"\n한국어 번역은 대기열에서 이어서 진행합니다.": "\nKorean translation will continue in the queue.",
|
||||
" ☆ 를 누르면 여기에 즐겨찾기가 추가됩니다 · 오른쪽 클릭: 폴더 추가": " Press ☆ to add bookmarks here · Right-click: add folder",
|
||||
" ({0}개는 이미 있음)": " ({0} already exist)",
|
||||
" (결과물 {0}개 함께)": " ({0} results moved too)",
|
||||
" (대기열)": " (queued)",
|
||||
" (동영상 {0}개)": " ({0} videos)",
|
||||
" (사용 불가)": " (unavailable)",
|
||||
|
|
@ -188,6 +189,7 @@
|
|||
"결과 폴더": "Output folder",
|
||||
"결과 폴더 열기 (동영상을 고르세요)": "Open output folder (choose a video)",
|
||||
"결과 폴더 열기: {0}": "Open output folder: {0}",
|
||||
"결과물 이동 실패: {0} ({1})": "Failed to move result: {0} ({1})",
|
||||
"계속 편집": "Keep editing",
|
||||
"고른 크기 이하에서 가장 좋은 화질 (영상에 없는 크기면 가까운 것)": "Best quality at or below the chosen size (nearest if the video lacks that size)",
|
||||
"고지 문서": "Notices",
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
"\n한국어 번역은 대기열에서 이어서 진행합니다.": "\n韓国語への翻訳はキューで続けて行います。",
|
||||
" ☆ 를 누르면 여기에 즐겨찾기가 추가됩니다 · 오른쪽 클릭: 폴더 추가": " ☆ を押すとここにブックマークが追加されます · 右クリック: フォルダー追加",
|
||||
" ({0}개는 이미 있음)": "({0}個は既にあります)",
|
||||
" (결과물 {0}개 함께)": "(成果物 {0}個も一緒に)",
|
||||
" (대기열)": "(キュー)",
|
||||
" (동영상 {0}개)": "(動画 {0}個)",
|
||||
" (사용 불가)": "(使用不可)",
|
||||
|
|
@ -188,6 +189,7 @@
|
|||
"결과 폴더": "出力フォルダー",
|
||||
"결과 폴더 열기 (동영상을 고르세요)": "出力フォルダーを開く(動画を選んでください)",
|
||||
"결과 폴더 열기: {0}": "出力フォルダーを開く: {0}",
|
||||
"결과물 이동 실패: {0} ({1})": "成果物の移動失敗: {0}({1})",
|
||||
"계속 편집": "編集を続ける",
|
||||
"고른 크기 이하에서 가장 좋은 화질 (영상에 없는 크기면 가까운 것)": "選んだサイズ以下で最も良い画質(動画にないサイズなら近いもの)",
|
||||
"고지 문서": "告知文書",
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
"\n한국어 번역은 대기열에서 이어서 진행합니다.": "\n韩语翻译将在队列中继续进行。",
|
||||
" ☆ 를 누르면 여기에 즐겨찾기가 추가됩니다 · 오른쪽 클릭: 폴더 추가": " 点击 ☆ 即可在此添加书签 · 右键: 添加文件夹",
|
||||
" ({0}개는 이미 있음)": "({0} 个已存在)",
|
||||
" (결과물 {0}개 함께)": "(成品 {0} 个一并移动)",
|
||||
" (대기열)": "(队列)",
|
||||
" (동영상 {0}개)": "({0} 个视频)",
|
||||
" (사용 불가)": "(不可用)",
|
||||
|
|
@ -188,6 +189,7 @@
|
|||
"결과 폴더": "输出文件夹",
|
||||
"결과 폴더 열기 (동영상을 고르세요)": "打开输出文件夹(请选择视频)",
|
||||
"결과 폴더 열기: {0}": "打开输出文件夹: {0}",
|
||||
"결과물 이동 실패: {0} ({1})": "成品移动失败: {0}({1})",
|
||||
"계속 편집": "继续编辑",
|
||||
"고른 크기 이하에서 가장 좋은 화질 (영상에 없는 크기면 가까운 것)": "不超过所选尺寸的最佳画质(视频没有该尺寸时取最接近的)",
|
||||
"고지 문서": "声明文件",
|
||||
|
|
|
|||
|
|
@ -402,7 +402,8 @@ class AppController extends ChangeNotifier {
|
|||
return n;
|
||||
}
|
||||
|
||||
/// 동영상을 이동 폴더 (환경 설정) 로 옮긴다. 옆에 있는 같은 이름의 자막 파일 (a.srt · a.ko.smi …) 도 함께.
|
||||
/// 동영상을 이동 폴더 (환경 설정) 로 옮긴다. 옆에 있는 같은 이름의 자막 파일 (a.srt · a.ko.smi …) 과
|
||||
/// 만든 결과물 (jj_mkv 의 a.mkv · a_AI.srt · a_ko.srt …) 도 함께 (결과물은 이동 폴더의 jj_mkv 로).
|
||||
/// 옮긴 동영상은 목록에서 뺀다. 작업 중인 것은 옮기지 않는다. 반환: (옮긴 수, 못 옮긴 이유들)
|
||||
Future<(int, List<String>)> moveVideos(List<VideoItem> targets) async {
|
||||
final dest = settings.moveTargetDir;
|
||||
|
|
@ -440,7 +441,15 @@ class AppController extends ChangeNotifier {
|
|||
_log(trf('자막 이동 실패: {0} ({1})', [p.basename(s), e]));
|
||||
}
|
||||
}
|
||||
_log(trf('이동: {0} → {1}{2}', [v.fileName, to, side.isEmpty ? '' : trf(' (자막 {0}개 함께)', [side.length])]));
|
||||
final results = await _moveResults(v.path, to);
|
||||
_log(trf('이동: {0} → {1}{2}', [
|
||||
v.fileName,
|
||||
to,
|
||||
[
|
||||
if (side.isNotEmpty) trf(' (자막 {0}개 함께)', [side.length]),
|
||||
if (results > 0) trf(' (결과물 {0}개 함께)', [results]),
|
||||
].join(),
|
||||
]));
|
||||
videos.remove(v);
|
||||
checked.remove(v);
|
||||
moved++;
|
||||
|
|
@ -454,6 +463,26 @@ class AppController extends ChangeNotifier {
|
|||
return (moved, errors);
|
||||
}
|
||||
|
||||
/// 만든 결과물 (jj_mkv 의 이름.mkv · 이름_AI.srt · 이름_ko.srt …) 을 옮긴 동영상의 jj_mkv 로. 옮긴 개수.
|
||||
Future<int> _moveResults(String oldVideo, String newVideo) async {
|
||||
final from = outputDirFor(oldVideo), to = outputDirFor(newVideo);
|
||||
if (p.equals(from, to) || !Directory(from).existsSync()) return 0;
|
||||
final stem = p.basenameWithoutExtension(oldVideo);
|
||||
final mine = RegExp('^${RegExp.escape(stem)}(\\.mkv|_[A-Za-z-]+\\.(srt|ass|ssa|smi|vtt|sub))\$', caseSensitive: false);
|
||||
var n = 0;
|
||||
for (final f in Directory(from).listSync().whereType<File>()) {
|
||||
if (!mine.hasMatch(p.basename(f.path))) continue;
|
||||
try {
|
||||
await Directory(to).create(recursive: true);
|
||||
await moveFileInto(f.path, to);
|
||||
n++;
|
||||
} catch (e) {
|
||||
_log(trf('결과물 이동 실패: {0} ({1})', [p.basename(f.path), e]));
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
/// 파일을 폴더 안으로 옮긴다 (같은 이름이 있으면 "이름 (2).mp4"). 다른 드라이브 · SD 카드면 복사 후 지운다. 옮긴 경로를 돌려준다.
|
||||
static Future<String> moveFileInto(String from, String dir) async {
|
||||
final stem = p.basenameWithoutExtension(from), ext = p.extension(from);
|
||||
|
|
|
|||
|
|
@ -34,6 +34,12 @@ void main() {
|
|||
final b = VideoItem(make('b.mkv').path);
|
||||
final busy = VideoItem(make('c.mp4').path)..status = JobStatus.running;
|
||||
make(p.join('done', 'b.mkv')); // 이미 있는 이름
|
||||
// 만든 결과물 (jj_mkv): a 의 것만 함께 옮긴다
|
||||
make(p.join('jj_mkv', 'a.mkv'));
|
||||
make(p.join('jj_mkv', 'a_AI.srt'));
|
||||
make(p.join('jj_mkv', 'a_zh-Hans.srt'));
|
||||
make(p.join('jj_mkv', 'ab.mkv'));
|
||||
make(p.join('jj_mkv', 'a_1_ko.srt'));
|
||||
c.videos.addAll([a, b, busy]);
|
||||
c.selected = a;
|
||||
|
||||
|
|
@ -45,6 +51,13 @@ void main() {
|
|||
expect(File(p.join(dir.path, 'other.srt')).existsSync(), isTrue, reason: '이름이 다른 자막은 그대로');
|
||||
expect(File(p.join(dest, 'b (2).mkv')).readAsStringSync(), 'b.mkv');
|
||||
expect(File(p.join(dir.path, 'a.mp4')).existsSync(), isFalse);
|
||||
for (final f in ['a.mkv', 'a_AI.srt', 'a_zh-Hans.srt']) {
|
||||
expect(File(p.join(dest, 'jj_mkv', f)).existsSync(), isTrue, reason: f);
|
||||
expect(File(p.join(dir.path, 'jj_mkv', f)).existsSync(), isFalse, reason: f);
|
||||
}
|
||||
for (final f in ['ab.mkv', 'a_1_ko.srt']) {
|
||||
expect(File(p.join(dir.path, 'jj_mkv', f)).existsSync(), isTrue, reason: '다른 동영상의 결과물 $f 는 그대로');
|
||||
}
|
||||
expect(c.videos, [busy]);
|
||||
expect(c.selected, busy);
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue