관리자 지시 (10/17, l): FTP · FTPS 를 탐색기 원격 탭으로. 평문 FTP 는 "암호화 안 됨" 경고, 처음 값은 FTPS, 비밀번호는 안전 저장소.
- lib/core/ftp.dart (새, 패키지 없음 - ftpconnect 3.0.0 은 dartssh2 ^3 에 묶여 우리 dartssh2 4.1.0 과 함께 못 씀):
· 명령 채널 RawSocket → 명시 FTPS 는 AUTH TLS 뒤 RawSecureSocket.secure (같은 연결을 TLS 로), 암시 FTPS (990) 는 연결하자마자 TLS. PBSZ 0 · PROT P
· 목록 MLSD (FEAT 에 MLST 가 있으면) 아니면 LIST (유닉스 꼴), 정보 · 만들기 · 지우기 (안쪽까지) · 옮기기 (RNFR/RNTO)
· 받기 · 올리기는 따로 연결 (REST 로 부분 읽기 - 동영상 건너뛰기 · 이어 받기). 자료 연결의 TLS 는 명령에 150/125 를 받은 뒤
· 자료 연결 주소는 명령 채널의 서버 주소로만 (PASV 가 알려 준 다른 주소로 가지 않음 - FTP 바운스 막기). EPSV 먼저
· FTPS 로 고른 서버가 평문만 되면 몰래 평문으로 내려가지 않고 이유를 알림
· 자체 서명 인증서: SFTP 호스트 키처럼 처음 한 번 지문 (SHA-256) 을 보이고 믿을지 묻고 (TOFU), 바뀌면 막음. 공인 인증서는 그대로
· DNS 강제를 따름 (FtpRegistry.resolveWithDns - SFTP 와 같게)
- vfs: ftp://<서버 id>/<경로> (isFtp · noStreamUrl → 받아서 열기, 표시 📂 · 평문은 ⚠, 임시 폴더 jj_ftp)
- 설정: ftpServers (비밀번호는 ftp.pw.<id> 안전 저장소, 설정 파일 · .bak · 보관본에서 뺌), 마스터 초기화에서 지움
- 화면: 환경 설정 > 파일 탐색기 > FTP · FTPS (추가 · 고치기 · 지우기 · 연결 확인, 암호화 고르기 - 평문은 빨간 경고),
탐색기 위 줄 탭 (평문은 ⚠ 이름) · [FTP 서버 추가] · 좁은 창 메뉴 · 길게 누르기 고치기 · 인증서 지문 안내 [지문 확인하고 연결]
시험: test/ftp_test.dart 7 - 설정의 비밀번호 (안전 저장소 · 보관본), 목록 줄 읽기, 실제 서버 (tool/ftp_test_server.py = pyftpdlib 2.2.0 ·
pyOpenSSL 26.4.0, 시험용 파이썬에만 - 앱에 안 들어감): 명시 FTPS (인증서 TOFU · 바뀐 인증서 막기 · 폴더 · 쓰기 · 목록 · 부분 읽기 · 옮기기 · 지우기),
암시 FTPS, 평문 FTP (+ FTPS 서버가 평문만이면 이유), 틀린 비밀번호 · 비밀번호 없음 · 닿지 않음.
sftp · master_lock · settings_store · webdav · explorer_webdav · explorer · sftp_explorer · licenses 와 함께 98 통과, analyze 문제 없음, l10n 빠짐 0.
시험 서버 메모: pyftpdlib 2.2.0 + pyOpenSSL 26 은 자료 연결 TLS 닫기에서 끝없이 되풀이해 STOR 가 끝나지 않는다 - 시험 서버에서만 덮어씀.
못 한 것: 실제 NAS (Synology 등) FTPS · TLS 세션 재사용을 요구하는 서버 (vsftpd require_ssl_reuse) 는 확인 못 함 (Dart 는 자료 연결의 TLS 세션 재사용을 못 함),
FTP 스트리밍 재생 (sftp_next 의 다리와 합칠 때 FtpRemote.openReadFrom 을 넣으면 됨), 경로 복사의 ftp:// 꼴.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
사용자 결정 88-1 (Windows 는 운영체제 그대로) · 88-4 (SMB3 암호화는 허용 + 안 되면 경고) 대로 Android 만.
- android/.../SmbBridge.kt (채널 jj_mkvmaker/smb, 뒤 스레드): smbj (SMB2 · SMB3, SMB1 없음) · Bouncy Castle 보안 제공자
(Android 기본에는 NTLM 의 MD4 가 없음) · 암호화 요청 (withEncryptData). 서버마다 연결 하나를 다시 씀, 파일은 손잡이로 1MB 조각.
오류를 종류로 (auth · unreachable · noShare · smb1 · permission · notFound). R8 keep 규칙 (smbj · mbassador · bouncycastle).
- lib/core/smb.dart: SmbServer (비밀번호는 안전 저장소 smb.pw.<id> 에만) · SmbRemote (RemoteClient) · SmbRegistry.
저장된 비밀번호 없음은 서버에 묻지 않고 알림, 게스트 (아이디 없음) 허용, info() 로 암호화 여부.
- vfs: smb:// 를 같은 원격 길로 (🗄), 재생 · 다른 앱은 받아서 (noStreamUrl = SFTP · SMB).
- 화면: 환경 설정 > 파일 탐색기 > SMB (Android 만) - 서버 · 포트 · 공유 · 시작 폴더 · 아이디 (비우면 게스트) · 비밀번호 · 도메인,
[연결 확인] 에서 암호화 안 되면 경고. 탐색기 탭 · ⋮ 메뉴 [SMB 서버 추가] · 탭 길게 누르기 = 고치기 · 폴더 고르는 곳.
179 바꿈: Android 에서 smb:// · \서버\공유 를 넣으면 "SMB 서버 추가로 넣으면 탭으로" 안내와 [SMB 서버 추가] (넣은 주소로 채움) · [WebDAV 서버 추가].
- 최상 · 마스터 초기화의 저장된 비밀번호 지우기에 SMB 도.
- 라이선스: SMBJ_LICENSES.txt (smbj LICENSE_HEADER · Bouncy Castle · SLF4J · MBassador 원문 + Apache 2.0 전문, smbj 는 NOTICE 파일이 없음),
라이선스 화면 · Android 고지, 판이 바뀌면 시험이 알림.
- 시험: smb_test (가짜 채널 - 1MB 조각 쓰기 · 읽기 · 목록 · 이름 바꾸기 · 지우기 · 시작 폴더 · 오류 글 · 저장된 비밀번호 없음 · 설정 · 주소 풀기),
179 시험 고침. 전체 837 통과 · 17 건너뜀, 새로 남은 임시 폴더 0. APK 빌드 (Kotlin 컴파일 · R8) 통과.
- 시험이 잡은 버그: 큰 조각 하나가 오면 1MB 로 나누지 않고 통째로 보냈다 → 나눔.
- 미완: 실제 smbj 연결 (Android 기기 + SMB 서버) 은 확인하지 못함 - 노트 10+ 등에서 PC 공유 폴더로 확인 필요.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
사용자 "진행" (10/17, 관리자 3a 전달) - 88 설계안의 제안값:
1) Windows SMB 는 운영체제 그대로 2) 키 암호는 안전 저장소 3) ssh-rsa 기본 끔 · 서버마다 켬 4) SMB3 암호화 (SMB 때) 5) 서버 rsync 는 다음 판.
이 커밋 (화면은 아직 없음 - 설정 화면 · 탐색기 탭은 다음 커밋):
- lib/core/remote_fs.dart: 원격 저장소 공통 동작 (RemoteClient). WebDAV (DavClient) 도 이것으로.
- lib/core/sftp.dart: SftpServer (설정, 비밀 값은 toJson 에 없음) · SftpRemote (dartssh2, 서버마다 연결 하나를 다시 씀) · SftpRegistry.
- 호스트 키: 믿은 지문이 없으면 연결하지 않고 지문 (SHA256:…) 을 알림 (SftpHostKeyException) → 화면이 묻고 저장.
바뀌면 막고 예전 · 지금 지문을 알림 (중간자 공격 안내).
- 비밀번호 · keyboard-interactive · 개인 키 (암호), 키 암호 틀림 · 키를 못 읽음 · 저장된 비밀번호 없음 · 닿지 않음 · 권한 · 없는 경로를 사람 말로.
- 오래된 서버: 처음엔 SHA-1 을 쓰지 않고 "오래된 ssh-rsa 허용" 을 안내, 서버마다 켜면 ssh-rsa · SHA-1 키 교환.
- DNS 강제를 따라 직접 연결 (집 안 이름 · 주소는 기기 DNS), 시작 폴더 (비우면 홈).
- 소켓 끊김의 쓰기 실패가 처리되지 않은 오류로 올라오지 않게.
- vfs: sftp:// 를 dav:// 와 같은 원격 길로 (isDav = 원격, isWebDav · isSftp 따로). 화면 "🔑 서버/경로", 받아서 열기는 jj_sftp.
- 설정: sftpServers (비밀번호 · 개인 키 · 키 암호는 안전 저장소 sftp.pw/key/kp.<id> 에만, 평문 파일에 쓰지 않음), .bak · 깨진 파일 가림,
최상 비밀번호 초기화의 "저장된 비밀번호 지우기" 에 SFTP 도.
- 재생 · 다른 앱: SFTP 는 스트리밍 주소가 없어 고른 파일만 받아서 (진행 · 취소) 틀고 같은 폴더 자막도 받음 (다음 파일로 넘어가지 않음 - 1차).
- 시험: test/sftp_test.dart 7개 (설정 · 경로 + paramiko 시험 서버: TOFU · 바뀐 키 · 틀린 비밀번호 · 닿지 않음 · vfs 전체 · 키 로그인 · ssh-rsa).
tool/sftp_test_server.py (paramiko 3.5.1 - 5.0 은 SHA-1 을 뺌), venv 는 ..\tools\sftp_test_py (없으면 건너뜀).
- 라이선스 고지 · 화면 · Android SMB 는 다음 커밋.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 데이터 (버그, 기기 확인 · 10.10 에도 있음): FFmpeg -y 가 처음부터 결과 MKV 에 써서, 다시 만들다 취소 · 실패하면 예전 완성본이 사라졌다
→ 이름.mkv.jjpart 에 만들고 다 된 뒤에만 storage.replaceFile, 취소 · 실패면 임시 파일만 지움
- 결과가 이미 있으면 시작 전에 묻기 (덮어쓰기 · 건너뛰기 · 다른 이름) + 환경 설정 '만들 MKV 가 이미 있으면' (처음 값 묻기)
- 240 집계: 이번 묶음의 이전 상태를 비우고, 시작 못 한 것은 취소로 셈
- 끝난 (코드 0) 뒤에 온 취소는 무시 - 성공으로 (Windows · Android)
- 폰 세로 작업 중 [취소] · 진행을 늘 보이는 자리에, 진행 글 'MKV 3개 중 2번째 · 36%'
- 시험: 가짜 FFmpeg 가 출력을 만들게 (queue_test), 모든 파일이 '있는' 가짜 저장소에서는 덮어쓰기 (ui_test)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 239 (버그, 기기 확인): 창을 보는 사이 다음 동영상이 시작하면 [지금 것만 취소] 가 그 다음 것을 취소했다 - FFmpeg 실행에 꼬리표 (MediaTool tag · cancelTagged), 이미 끝났으면 알리고 다시 묻기
- 240 (사용자 편의, 기기 확인): 여럿이 동시에 돌면 [그대로 두기] · [모두 취소 (n개)], 목록 줄의 ■ 로 하나만
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 186 (사용자 편의, 기기 확인 지적): 묶음 실행 중 취소를 누르면 기다리는 항목이 있을 때 세 가지 중 고르기
- 187 (버그): 취소한 항목이 실패로 보이던 것 - JobStatus.cancelled, 회색으로 보이고 기록에 성공 · 취소 · 실패 / 전체
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
화면 언어 따르기 (처음 값) / 한국어 / English / 日本語 / 中文 / 직접 고르기 (자막 언어 목록).
화면은 일본어인데 한국어 자막을 기본으로 원하는 경우처럼, 고른 언어가 화면 언어보다 먼저.
설정 preferredSubtitleLanguage ('' = 화면 언어 따르기). i18n_small_test 에 시험.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 다른 드라이브 · NAS 로는 복사라 큰 동영상이 1초 넘게 목록에 남아 보였다 (1GB 시험 파일 M: → C: 1,079ms, 같은 드라이브 22ms).
- 데이터 버그 고침 (moveFileInto): 다른 드라이브로 복사한 뒤 원본을 지우지 못하면 (열려 있음 등) 대상 폴더에 사본이
남아 두 벌이 됐다. 이제 방금 만든 사본을 지우고 오류를 낸다 (원본은 그대로).
같은 함수를 쓰는 app_controller 안의 다른 두 곳 (옆 자막 · jj_mkv 결과물 함께 옮기기) 도 시험으로 확인했다:
자막 · 결과물을 열어 둔 채 옮기면 동영상만 옮겨지고, 자막 · 결과물은 원래 자리에 하나만 남는다
(고치기 전 코드로는 이 시험이 실패하는 것도 확인).
- move_test: 옮기는 중 목록에 없음 → 실패하면 복원 · 대상에 사본 없음, 함께 옮기는 파일의 실패.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 40/54: WebDAV · OpenSubtitles 비밀번호를 안전 저장소 (Android Keystore · Windows DPAPI) 로
- 95~114: rsync 지우기 확인 · 미리 보기 · 좁은 화면 확인 창 · 실시간 동기화 멈춤 알림
- 99: 시작 메뉴 바로 가기 (AUMID) · jjmkvmaker:// · Windows 알림 꺼짐 안내
- 102: 질문을 설정으로 · 시스템 언어 따르기
- 113 · 117~120: 보기 화면 막대 · 계속 보기 · 두 쪽 나눠 보기 · 회전 · 반전 · 좁으면 ⋮ 메뉴
- 115 · 116: 자동 백업 복원 알림 · 권한 안내와 자동 다시 분석
- 118 · 122: 탐색기 좌우 ⇆ / 위아래 ⇅ 버튼 · 경로로 가면 새로 읽어 펼침
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
근거: 감독 세션 지시 20번 (설정 파일을 읽다 실패하면 말없이 모든 설정을 처음 상태로 켜고, 무엇이든 바꾸면 원래 설정이 영영 사라짐).
- 저장: settings.json.tmp 에 다 쓴 뒤 바꿔치기 (쓰는 도중 앱이 끝나도 깨지지 않게), 한 번에 하나씩.
바꿔치기 전의 정상 파일은 settings.json.bak.
- 읽기 실패: 깨진 파일은 settings.broken-(시각).json 으로 보관 (다음 저장에 덮이지 않게), .bak 으로 되살림.
settings.json 만 없으면 (바꿔치기 도중 끝남) .bak 으로. 백업도 없으면 처음 설정.
- 켤 때 알림 창 (Windows · Android): 백업으로 되살렸는지 / 처음 설정인지, 보관한 파일 위치, 원인. 작업 기록에도.
- 시험: settings_store_test (바꿔치기 · .bak · 깨진 파일 · 백업 없음 · .bak 만 있음).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
근거:
- 감독 세션 지시 (폰 · S10 Ultra 를 사용자처럼 써 본 결과) 2 · 3 · 4 · 7 · 8 · 9 · 13 · 15번
- 사용자 결정 (10/8): 브라우저 소리 멈춤을 설정으로 (기본 켜짐), 정리 창은 임시 · 받다 만 다운로드만 미리 체크
- 2: 좁은 화면 MKV 화면 둘째 줄은 글자를 숨기지 않고 옆으로 밀어 봄, [MKV 만들기] 맨 앞.
변환 설정 줄은 줄바꿈 ([화면 · 색 보정] 이 세로에서 안 보이던 것).
- 3: 좁은 화면 맨 위 줄: 이동 아이콘 아래 짧은 이름 (홈 · MKV · 브라우저 · 탐색기 · Rsync · 다운로드 · 뒤로),
[환경 설정] 옆에는 ⋮ 메뉴 (화면 크게 · 작게 · 기본 크기 · 종료) - 종료가 설정 바로 옆이라 잘못 누르던 것.
- 4 · 15: 브라우저 주소 칸이 좁으면 (폰 세로 · 태블릿 세로 · 폰 가로) 홈 · 번역 · 즐겨찾기 · 작업 현황 · 외부 브라우저를
⋮ 메뉴로 (없애지 않음). 주소가 "http" 만 보이거나 사라지던 것.
- 7: Android 에서 "탐색기에서 끌어다 놓아도" 안내 뺌. 켤 때 "⚠ 사용할 수 없는 코덱" 기록 뺌 (코덱 목록에 "(사용 불가)" 로 보임).
- 8: 좁은 화면에 동영상이 없으면 한 화면에 안내 + [동영상 추가].
- 9: Android 재생 화면 버튼 크게, 재생 버튼 줄과 나머지 줄을 나눔.
- 13: 넓은 화면의 동영상 목록 칸을 화면 너비의 40% (320~640) 로 - 태블릿 세로에서 제목이 앞부분만 보이던 것.
- 사용자 결정: 환경 설정 > 웹 브라우저 "다른 화면으로 가면 페이지 소리 멈춤" (기본 켜짐).
- 사용자 결정: 저장 공간 정리 창은 작업 임시 파일 · 받다 만 다운로드만 미리 체크.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 플레이어 (mpv) 에 주소 + 인증 헤더로 넘김 (자체 서명 인증서면 tls-verify=no), 건너뛰기는 서버 Range 요청
- 같은 폴더 동영상으로 재생 목록, 같은 폴더 자막은 작으니 임시로 받아서
- 외부 플레이어 · VLC · 기본 프로그램에는 아이디를 넣은 주소로
- 탐색기의 "이 폴더의 동영상 재생" 도 WebDAV 에서
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 환경 설정 > 파일 탐색기 > WebDAV: 서버 추가 · 고치기 · 지우기 · 연결 확인 (기본 인증, 인증서 확인 안 함)
- 위쪽 "SD 카드" 옆 서버 탭 (없으면 "WebDAV" 탭 → 바로 추가), 경로 dav://서버/경로
- 목록 · 새 폴더 · 이름 변경 · 삭제 · 찾기 · 복사 · 이동 (같은 서버는 MOVE), 열기 · 재생은 임시로 받아서
- Rsync · lsync: 한쪽이 WebDAV 면 앱이 크기 · 시각 비교로 맞춤 (-u · --remove-source-files 따름)
- PROPFIND 에 Content-Length (chunked 면 일부 서버가 남은 본문을 다음 요청으로 오해)
- Android: http:// NAS 연결 허용 (usesCleartextTraffic)
- 화면에는 내부 id 대신 "☁ 서버 이름/경로"
- 시험: webdav_test (시험 서버) · explorer_webdav_test · real_dav_test (JJ_REAL_DAV 일 때 실제 서버)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 위쪽 공통 버튼에 [파일 탐색기], 환경 설정 > 홈 화면에 "파일 탐색기" (앱을 켜면 바로)
- 두 창 (트리: 누르면 그 자리에서 펼치기 · 접기), 저장 장치 고르기 (Windows 드라이브 · Android 저장소)
- 동영상: 누르면 기본 동작 (내장 플레이어 또는 확장자별 재생 프로그램), 길게 누르기 · 오른쪽 클릭 메뉴
(내장 플레이어로 재생 · 다른 앱으로 열기 · MKV 목록에 추가 · 이름 변경 · 복사 / 이동 · 삭제 · 정보)
- 썸네일 · 해상도 · 길이 (작업 중에는 썸네일을 만들지 않음), 그림 파일 미리 보기
- 가운데 버튼: 상위 폴더 · 새로 고침 · 재생 · MKV 목록에 추가 · 새 폴더 · 이름 변경 · 복사 · 이동 · 삭제 ·
찾기 · 정렬 기준 · 숨은 항목 · 내역 · 창 배치 · 버튼 구성
- 창 배치: 두 창 / 한 창, 좌우 / 위아래 / 화면 모양 따라, 버튼 줄 두 창 사이 / 끝 / 숨김
- 버튼 구성: 보일 버튼 · 순서
- 다른 앱으로 열기: Windows "연결 프로그램" 창 · Android 앱 고르기 (FileProvider, SD 카드 포함)
- 여러 개 지울 때 확인 창에 이름 · 폴더를 보여 준다
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 모든 화면 글자를 tr() / trf() 로 (한국어 원문이 사전 열쇠), assets/l10n 에 영어 · 일본어 · 중국어 사전
- 더한 언어는 이 기기의 NLLB 번역 모델로 영어 사전을 자동 번역해 설정 폴더 l10n 에 저장
- 언어 이름 · 선택 목록 · 모델 이름은 화면에 보일 때 번역 (파일명 인식 규칙은 그대로)
- tool/l10n: 새 글자 감싸기 · 사전 점검
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
"ffmpeg 오류 (코드 1) … No such file or directory" 대신 "동영상 파일이 없습니다 (옮겨졌거나 지워졌습니다)".
여러 개를 할 때는 그 동영상만 실패로 두고 다음으로 넘어간다 (지금과 같음).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- CP949 등 UTF-8 이 아닌 자막: MKV 만들기 · 자막 편집기 열기가 실패하던 것 (Android 의 FFmpeg 에 iconv 없음)
→ 앱이 UTF-8 사본을 만들어 넘김 (모든 플랫폼 같은 방식)
- 플레이어: CP949 SMI 자막이 보이지 않던 것 → UTF-8 SRT 사본으로 (Android). 'auto' 를 켜진 자막으로 여겨
jj_mkv 자막 (번역 · 받은 자막) 을 자동으로 켜지 않던 것. 같은 자막이 메뉴에 두 번 보이던 것
- 자막 편집기 미리보기: 같은 폴더 자막을 열지 못하면 "영상 재생 오류" 가 뜨던 것
- MKV 만들기 실패 시 0 바이트 MKV 가 남던 것 (시작 전 실패는 전에 만든 MKV 를 그대로 둠)
- AV1 영상 재인코딩 (Android FFmpeg 에 AV1 디코더 없음): "ffmpeg 오류 (코드 69)" 대신 원본 유지 안내
- 임시 파일: 캐시 폴더 → 앱 데이터 폴더 (저장 공간이 모자라면 Android 가 쓰는 중인 임시 파일을 지움)
- [폴더 열기] · 다운로드 폴더 · 외부 브라우저로 열기: Android 에서 아무 동작도 안 하던 것 → 파일 앱 · 기본 브라우저
- 플레이어의 팝업 · 창 크기 · 끌어다 놓기 안내 숨김 (PC 전용), "이 PC" → "이 기기"
- 취소한 다운로드에 속도 · 남은 시간이 남던 것
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 지난 실행이 정상으로 끝나지 않았으면 켤 때 알림 (session.json, 30초마다 살아 있는 시각 기록)
- 작업 기록을 설정 폴더의 app.log 에도 저장 (2MB 넘으면 app.log.1)
- 다운로드 시작 · 완료 · 실패를 작업 기록에 남김
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 끌어다 놓기를 앱 전체에서 받아 동영상 목록에 추가 (안내 테두리 · 결과 알림)
- 화면 크기 조절 버튼 (70~160%) 과 기본 화면 크기 설정
- MKV 화면: 폴더 열기 버튼, 동영상 목록 오른쪽 클릭 메뉴
- 위쪽 막대가 창 너비에 맞춰 줄어듦 (설정 · 종료 버튼이 밀려나지 않게)
- WebView2 환경을 만들기 전에 COM 을 다시 준비, 실패 결과를 붙들지 않음,
3초마다 COM 상태 확인 (풀려 있으면 다시 준비하고 작업 기록에 남김)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 버전 표기를 년.월.일_순번 으로 변경 (tool/next_version.ps1)
- 동영상 목록 여러 개 선택 · 정렬, 자막 만들기 / 자막 만들기 & MKV 만들기 /
선택한 파일 재생 일괄 실행
- 다운로드: 동영상 추가 버튼, 완료시 자동 동영상추가, 받은 크기 / 전체 크기,
yt-dlp 진행률 출력 복구 (--no-quiet --progress), 영상 + 음성 진행률 합산
- YouTube 쿠키를 못 읽으면 앱 안 브라우저 쿠키 → 쿠키 없이 순서로 재시도
- 모든 화면 오른쪽 위에 CPU · MEM · DISK, 환경 설정 · 종료 버튼
- 단축키로 창 보이기 / 숨기기 전환, 종료 시간 단축 (exit.log 에 단계별 시간)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>