본문으로 건너뛰기

CatchCatch

CatchCatch 개발일지 · 1편부터 7편까지

CatchCatch 의 개발일지 1편부터 7편까지를 한 글로 묶었다. 맨 위에 진행 상황을 나타내는 마인드맵과 개발 시퀀스를 둔다.

2026. 10. 29

개요

CatchCatch 는 화면 녹화, 회의·강의 녹음, 스크린샷을 한 프로그램에서 다루는 Windows 프로그램이다. 이 글은 1편부터 7편까지의 개발일지를 한 곳에 묶은 것이다. 맨 위의 마인드맵은 지금까지 한 일, Claude 가 하는 일, SHIN 이 할 일, 앞으로 할 일을 나눈다. 그 아래 개발 시퀀스는 판별 작업의 기간과 진행률, 선후 관계를 나타낸다. 날짜가 오늘 이후인 작업은 계획(안)이다.

가지를 누르면 아래 단계가 펼쳐지고 다시 누르면 접힘 · 번호는 「핵심 1-2」 꼴
      • 1MP3
      • 2M4A
      • 3WAV
      • 4FLAC
      • 1마이크
      • 2시스템 소리
      • 3둘을 섞기
      • 1섞기
      • 2따로
      • 3둘 다
      • 116비트
      • 224비트
      • 332비트
    • 5PC 안 전사 SRT
    • 6소리 싱크 수동 보정
      • 1구석 네 곳
      • 2크기 15~33%
    • 2웹캠 배경 제거
    • 3크로마키
    • 4영역 가리기
    • 5워터마크
    • 6로고
    • 7방송 송출
    • 1HDR 10비트 녹화
    • 2HDR 스크린샷
    • 1모니터 하나
    • 2모든 모니터
      • 1미리보기에서 끌어 고르기
      • 1창 이동 따라감
      • 1640×360~1920×1080
    • 6전체화면 게임(DDA)
    • 7모니터 N개 골라 녹화
    • 8게임 후킹
    • 1한국어 화면
    • 2UI 언어 전환
    • 1Windows
    • 2Mac·Linux
    • 3Android
    • 1소음 제거
    • 2음량 맞춤
      • 1H.264
      • 2HEVC
      • 3AV1
    • 2MP4
      • 1MP3
      • 2M4A
      • 3WAV
      • 4FLAC
    • 4MOV·MKV·WebM
    • 5ProRes·VP9
    • 6영상 안 Opus·PCM
CatchCatch구현 46 / 802026.10.29. 기준
      • 1원본
      • 21080p
      • 31440p
      • 44K
      • 58K
      • 675%
      • 750%
      • 1H.264 한계 4096×2304 검사
      • 2넘으면 HEVC 로 바꿈
    • 3AV1 코덱
    • 416K 녹화
      • 115
      • 224
      • 330
      • 460
      • 5120
      • 6144
      • 7240
      • 1캡처 방식 자동·GDI·DDA
      • 260 fps 넘으면 DDA 자동
      • 1자동 탐지
      • 2NVENC
      • 3QSV
      • 4AMF
      • 5CPU
      • 1놓친 프레임 채우기
      • 2실제·놓친 프레임 표시
      • 1모니터
      • 2모든 모니터
      • 3영역
      • 4창
      • 1PNG
      • 2JPG
      • 3WebP
      • 10초
      • 23초
      • 35초
      • 410초
      • 1유리 단추
      • 2작은 막대
      • 3단축키
    • 5클립보드 복사
    • 6스크롤 캡처
    • 7연속 캡처
    • 8찍은 뒤 편집
      • 1분 단위 설정
      • 2키프레임에서 자르기
      • 3조각별 표식 기록
      • 1MB 단위 설정
      • 1조각 MP4 임시 파일
      • 2녹화 일지
      • 3다음 실행 때 살리기·나중에·버리기
      • 4WAV 머리 고치기
      • 5표식 함께 복구
      • 1다시 담기
      • 2참조 파일로 H.264 되살리기
      • 1표식 메모를 챕터 제목으로
      • 1단축키·단추로 찍기
      • 2메모 입력
      • 3txt·csv 저장
        • 1경과
        • 2벽시계
        • 3둘 다
        • 1소리
        • 2화면 깜빡임
      • 1노란 고리
      • 1오른쪽 파란 고리
      • 2가운데 초록 고리
        • 1볼펜
        • 2만년필
        • 3붓
        • 4형광펜
        • 1지나간 자리만
        • 2넓게
        • 3획 통째로
        • 1형광
        • 2실선
        • 3점선
        • 4일점쇄선
        • 5이점쇄선
        • 1가로
        • 2세로
        • 3자유
        • 1직선
        • 2화살표
        • 3상자
        • 4타원
        • 5삼각형
        • 6마름모
        • 7오각형
        • 8육각형
        • 9별
      • 4손그림 자동 인식
      • 5도형 채우기
        • 1이동
        • 2색 바꾸기
        • 3복사
        • 4삭제
      • 2글자 넣기
      • 3레이저 포인터
      • 1펜 태블릿 필압
      • 2터치 입력
      • 3손바닥 무시
    • 8필기 JSON 저장
    • 9화이트보드
    • 10녹음 모드 필기
      • 1시작·정지
      • 2일시정지
      • 3표식
      • 4스크린샷
      • 5필기 켜기·끄기
      • 6아래 창 조작
      • 7필기 모두 지우기
    • 2시작 전 초 읽기
      • 1시각 지정
    • 4시간 지나면 정지
      • 1무음 N분
    • 6절전 막기
    • 7되감기 버퍼
      • 1재인코딩 없이 자르기
    • 2이어 붙이기
    • 3MP3 추출
    • 4GIF 만들기
    • 5표식 기준 자르기
      • 1필기 JSON 불러오기
      • 2영상에 다시 그리기
1구현1미구현초록 가지 핵심기능 9개 · 파란 가지 주요기능 6개 · 가지 오른쪽 숫자는 2차 기준 구현 수/전체
그림 1. CatchCatch 마인드맵(2026.10.29. 기준)

묶음 작업 이름을 누르면 하위 작업이 펼쳐짐 · 막대에 마우스를 올리면 기간과 상태 표시
지난 기간
오늘 10.29
ID
작업 이름
기간
시작
완료
진행률
선행
2026.09.9.079.149.219.282026.10.10.0510.1210.1910.262026.11.11.0211.0911.1611.2311.302026.12.12.0712.14

1
2일
9.09
9.10
100%
✓ 해결 완료
1.1
v1.0.0.0 녹화·녹음 통합
1일
9.09
9.09
100%
✓ 해결 완료
1.2
v1.0.0.1 소리 맞춤
1일
9.09
9.09
100%
✓ 해결 완료
1.3
v1.0.0.2 창 따라가기·인코더
1일
9.10
9.10
100%
✓ 해결 완료
2
기능 정의·이름 CatchCatch
2일
9.29
9.30
100%
✓ 해결 완료
3
v1.0.1.0 원천 보완·설치 파일
2일
10.01
10.02
100%
✓ 해결 완료
4
v1.0.2.0 화면 재구성·필기
6일
10.02
10.07
100%
✓ 해결 완료
5
기능 지도 조사
1일
10.27
10.27
100%
✓ 해결 완료
6
v1.0.2.1 설정 결함 수리
1일
10.28
10.28
90%
게시 대기

7
8일
10.28
11.04
65%
진행
7.1
개발·wine 시험
1일
10.28
10.28
100%
✓ 해결 완료
7.2
Windows 실기 1차
1일
10.29
10.29
100%
✓ 해결 완료
7.3
실기 결함·필기 막대 반영
4일
10.30
11.02
30%
7.2
진행
7.4
게시(개발일지·본편)
2일
11.03
11.04
0%
7.3
계획(안)
9
실기 시험 약 60회
5일
11.04
11.08
0%
7.4
계획(안)
10
v1.0.3.1 실기 결함 수정
4일
11.09
11.12
0%
9
계획(안)
M
화면 개편 방식 결정(SHIN)
0일
11.03
11.03
0%
화면 개편 방식 결정(SHIN)

11
27일
11.04
11.30
0%
계획(안)
11.1
목업·시험판
11일
11.04
11.14
0%
M
계획(안)
11.2
본 개발·실기
16일
11.15
11.30
0%
11.1
계획(안)
12
v1.1.1.0 녹화본 편집
12일
12.01
12.12
0%
11.2
계획(안)
완료(해결된 지난 작업)진행게시 대기계획(안)결정 시점묶음 작업지난 기간
그림 2. 개발 시퀀스. 막대의 진한 부분은 진행률, 마름모는 SHIN 의 결정 시점, 붉은 세로선은 오늘이다.

편별 목록

편 제목 판 날짜 상태
1편 녹화 프로그램과 녹음 프로그램을 하나로 v1.0.0.0 2026.09.09. 게시
2편 소리가 0.15초 앞서 있었다 v1.0.0.1 2026.09.09. 게시
3편 기존 것보다 나쁘지는 않아야 한다 v1.0.0.2 2026.09.10. 게시
4편 핵심기능 아홉 가지를 정한다 v1.0.1.0 계획 2026.09.29. 게시
5편 후보를 쉰아홉까지 세고 이름을 CatchCatch 로 정한다 v1.0.1.0 계획 2026.09.30. 게시
6편 이름 변경 및 원천 보완 v1.0.1.0 2026.10.01. 게시
7편 화면 재구성과 필기·스크린샷·고주사율 v1.0.2.0 2026.10.03. 게시
8편 동작하지 않던 설정 네 가지 수리 v1.0.2.1 2026.10.28. 빌드 완료, 판올림 때 게시
9편 녹화 파일 분할 및 비정상 종료 복구 v1.0.3.0 2026.10.29. 실기 결함 수리 뒤 게시

1편. 녹화 프로그램과 녹음 프로그램을 하나로 · v1.0.0.0

2026.09.09. 게시

목적

화면 녹화, 회의 녹음, 강의 녹음을 하나의 프로그램에서 수행할 수 있도록 프로그램을 만들고자 한다. 파일 이름 규칙과 버전표시(marker)은 사용자가 정한 규칙대로 남긴다. 이 판에서는 기본 기능만 다루고, 다른 프로그램에 없는 기능은 다음 판으로 미룬다.

계획

  1. 기존 녹화·녹음 프로그램과의 차이를 표로 정리
  2. Python + PySide6 로 구조 잡기(mss 캡처, sounddevice 녹음, ffmpeg 인코딩·합치기)
  3. 녹화 모드(모니터·영역), 녹음 모드(MP3·M4A·WAV), 버전표시, 전역 단축키, 트레이
  4. 장치 없이 도는 엔진 시험(가짜 화면·사인파)과 진짜 화면 시험
  5. 개발일지 1편과 캡처

체크리스트 6/8

항목 상태 비고
차별성 표와 설계 문서(DESIGN.md) 완료
녹화 모드: 모니터·영역 → MP4, 마이크·시스템 소리 동시 기록 완료
녹음 모드: MP3·M4A·WAV, 버전표시 txt·csv 완료
전역 단축키·트레이·파일 이름 규칙 완료
enginetest 3묶음 전부 통과 완료
realtest: 진짜 화면을 진짜 단추로 5.10초 녹화, 153프레임 완료
Windows exe 미완 PySide6 는 64비트 Windows 전용이라 이 판은 PC 의 run0.bat 에 맡김
시스템 소리(WASAPI loopback)·배율 화면 실기 미완 실제 PC 필요

1. 왜 만드는가

화면 녹화는 기존 녹화 프로그램, 회의·강의 녹음은 기존 녹음 프로그램이나 스마트폰 앱을 썼다. 기존 녹화 프로그램 가운데 유료인 것은 무료판에 워터마크가 붙는다. 무료인 것은 방송용이라 장면·소스·믹서를 먼저 이해해야 단추가 보인다. 기존 녹음 프로그램은 버전표시가 앱 내부 저장소에만 기록되어 파일을 다른 곳으로 옮기면 버전표시가 사라진다.

이 세 프로그램에 공통으로 없는 기능이 두 가지 있다. 첫째, 파일 이름 규칙을 사용자가 정할 수 없다. 둘째, 녹음 중에 지금 이 자리를 표시해 두고 그 목록을 파일 곁에 텍스트로 남기는 기능이 없다. 이 두 가지는 GenealogyKSIC 에서 정한 「연도(0000).월(00).일(00)., 시간(00).분(00)., 주석.확장자」 규칙과 회의 전사 작업에 필요하다. 따라서 직접 만들기로 하였고, 이름은 GenealogyRecording 으로 정하였다.

2. 무엇을 만드는가

항목 기존 녹화 프로그램 A
(유료)
기존 녹화 프로그램 B
(무료)
기존 녹음 프로그램 A
(무료)
GenealogyRecording
라이선스 유료
(무료판 워터마크)
무료
(GPL)
무료 무료
(자체 제작)
화면 녹화 O O X O
음성 녹음 X X O O
버전표시(marker) 없음 없음 앱 내부 파일 곁 txt·csv
파일 이름 날짜 고정 날짜 고정 번호 붙은 고정 이름 날짜.시각.주석
내부 수정 불가 C++ 불가 Python, 판올림 기록

1판(v1.0.0.0)의 범위는 다음과 같다. 녹화 모드는 모니터 전체, 특정 모니터, 끌어서 고른 영역을 MP4(H.264)로 기록하고, 마이크와 시스템 소리를 함께 담는다. 녹음 모드는 마이크 소리를 MP3·M4A·WAV 로 기록하며, 선택하면 시스템 소리도 함께 담는다. 버전표시는 Ctrl+Shift+M 으로 찍고 메모를 붙일 수 있으며, 결과 파일 곁에 이름.표식.txt 와 이름.표식.csv 로 남는다. 전역 단축키는 Ctrl+Shift+R 이 시작·정지, Ctrl+Shift+P 가 일시정지이며, 녹화가 시작되면 창은 트레이로 내려간다.

이 판에 넣지 않은 기능은 마우스 커서 그리기, 특정 창 따라가기, 웹캠 덧붙이기, 전사다. 커서는 캡처 라이브러리가 찍지 않으므로 따로 덧그려야 하며, 이것은 다음 판에서 다룬다.

3. 스택과 구조

언어와 화면 도구는 GenealogyImage 와 같이 Python 과 PySide6 를 쓴다. 선택한 이유도 GenealogyImage 와 같다. 화면 캡처는 mss, 소리는 sounddevice(PortAudio), 인코딩·합치기·변환은 ffmpeg 다. ffmpeg 는 imageio-ffmpeg 패키지가 실행 파일을 동봉하므로 따로 내려받을 것이 없다.

src/genealogyrecording/
  app.py           QApplication, 팔레트, 아이콘(코드로 그림)
  mainwindow.py    창. 모드 전환 · 설정 · 큰 단추 · 최근 결과
  settings.py      %APPDATA%/GenealogyRecording/settings.json
  naming.py        0000.00.00., 00.00., 주석.확장자
  screen.py        mss 모니터 목록 · BGRA 프레임
  videowriter.py   프레임 → ffmpeg 표준입력 → MP4
  audio.py         장치 목록 · WASAPI loopback 탐지 · WAV 기록
  session.py       한 번의 녹화를 통째로(시작·일시정지·표식·정지·마무리)
  markers.py       표식 목록 · txt/csv
  regionselect.py  화면 위 반투명 덮개에서 영역 끌기
  hotkeys.py       RegisterHotKey(Windows) / QShortcut(그 밖)
  levelmeter.py    입력 레벨 막대
  ffmpegtool.py    ffmpeg 찾기 · mux · 변환

4. 결정 세 가지

4-1. 프레임은 파이프로 보내고, 소리는 파일로 쓰고, 마지막에 합친다

영상과 소리를 처음부터 한 ffmpeg 프로세스에 넣는 방법도 있다. 그러면 소리 장치가 ffmpeg 의 dshow 로 잡혀야 한다. 한국어 Windows 에서는 장치 이름이 깨진다. 시스템 소리(스테레오 믹스)가 기본으로 꺼져 있는 PC 도 많다. 따라서 영상과 소리의 경로를 분리하였다. 영상은 mss 프레임을 ffmpeg 표준입력으로 흘려 임시 MP4 로, 마이크와 시스템 소리는 각각 WAV 로, 정지하면 셋을 ffmpeg 로 합친다.

cmd = [exe, "-f", "rawvideo", "-pix_fmt", "bgra",
       "-s", f"{w}x{h}", "-r", str(fps), "-i", "-",
       "-an", "-c:v", "libx264", "-preset", "veryfast", "-crf", "23",
       "-pix_fmt", "yuv420p", "-movflags", "+faststart", out]

4-2. 박자를 놓치면 직전 프레임을 다시 보낸다

화면이 크거나 PC 가 느리거나 다른 프로그램이 CPU 를 쓰는 순간에는 캡처가 늦어진다. 그때 프레임을 건너뛰면 영상이 실제 시간보다 짧아지고 소리와 어긋난다. 따라서 캡처 스레드는 시계를 기준으로, 놓친 박자 수만큼 같은 프레임을 다시 보낸다. 영상 길이 = 프레임 수 ÷ FPS 가 항상 실제 시간과 같아진다.

due = base + tick * period
if now < due: sleep(min(due - now, 0.05)); continue
frame = source.grab()
pipe.write(frame); tick += 1
behind = int((monotonic() - base) / period) - tick
for _ in range(min(behind, fps)):          # 놓친 박자만큼 채움
    pipe.write(frame); tick += 1

일시정지는 박자를 세지 않는다. 재개할 때 base 를 멈춘 시간만큼 뒤로 옮겨 시계를 잇는다.

4-3. 시작 시각 차이는 itsoffset 으로

영상 스레드와 소리 스레드는 같은 순간에 뜨지 않는다. PortAudio 장치가 열리는 데 0.1~0.5초가 든다. 각 스레드가 첫 프레임·첫 블록을 받은 monotonic() 을 적어 두고, 소리가 늦은 만큼 합칠 때 -itsoffset 으로 앞에 무음을 넣는다.

off = recorder.started_at - video.started_at
args += ["-itsoffset", f"{off:.3f}", "-i", wav]

5. 화면

녹화 모드
녹화 모드. 원천(모니터·영역), 화질(FPS·CRF), 소리(마이크·시스템), 저장(폴더·주석). 아래에 레벨 미터, 시간, 시작 단추.
녹음 모드
녹음 모드. 형식은 MP3·M4A·WAV. 버전표시 설명이 형식 옆에 있다.
녹화 중
녹화 중. 설정은 잠기고, 버전표시 하나를 찍은 상태. 레벨 미터가 입력 크기를 표시한다.
정지 뒤
정지 뒤. 최근 결과 목록에 길이·파일 이름·버전표시 수. 두 번 누르면 연다.

위 그림은 클라우드의 가상 화면에서 가짜 원천으로 찍은 것이라 「화면 없음」「마이크 없음」이 보인다. 실제 PC 에서는 모니터와 장치 이름이 채워진다.

6. 디버깅

6-1. 'Event' object is not callable

첫 시험에서 정지 직후 스레드 join 이 죽었다. 원인은 이름 충돌이다. threading.Thread 는 내부에서 self._stop() 메서드를 쓴다. 정지 신호를 self._stop = threading.Event() 로 두는 바람에 그 메서드를 덮어썼다. 스레드가 끝날 때 파이썬이 _stop() 을 부르고, Event 는 호출할 수 없으니 예외다. _stop_ev 로 바꿨다. 스레드를 상속할 때 밑줄 하나짜리 이름은 부모 것과 겹치는지 먼저 본다.

6-2. flush of closed file, 그리고 moov atom not found

두 번째 시험에서 MP4 가 48바이트짜리 빈 파일로 남았다. ffmpeg 표준입력을 close() 한 뒤 communicate() 를 불렀는데, communicate() 는 입력이 없어도 stdin 을 한 번 더 flush 하려 든다. 이미 닫힌 파일이므로 예외가 나고, 그 예외 처리에서 kill() 이 불려 ffmpeg 가 moov 를 쓰지 못한 채 종료되었다. 순서를 stdin 을 닫고, stderr 를 읽고, wait 하는 것으로 바꿨다.

p.stdin.close()
err = p.stderr.read()
p.wait(timeout=120)

6-3. 표본율이 다른 원천

마이크는 48000Hz, WASAPI loopback 은 장치 기본값(44100 인 경우가 많음)이다. WASAPI 공유 모드는 장치 기본 표본율만 받으므로 녹음 쪽은 장치 값을 따르게 했고, 합칠 때는 aresample=48000 을 각 입력에 먼저 걸고 amix 한다. 44100 과 48000 을 섞은 시험은 통과했다.

7. 시험

7-1. 장치 없이 엔진만

장치가 없는 곳에서도 엔진을 시험할 수 있어야 한다. FakeSource(색이 바뀌는 회색 프레임)와 FakeRecorder(440Hz 사인파를 실시간으로 흘림)를 두고 scripts/enginetest.py 가 세 묶음을 돈다.

[1] 파일 이름
  ok   주석 있음 / 주석 없음 / 금지 문자 치환 / 중복 이름 (2)
[2] 녹화 모드 (가짜 화면 + 마이크 + 시스템 소리)
  ok   결과 ok
       2026.09.09., 09.57., 시험.mp4  streams=['video', 'audio']  dur=3.03
  ok   영상+소리 트랙 / 길이 3초 안팎 (일시정지 1초 제외) / 세션 시간 3.00
  ok   프레임 60 (중복 0) / 표식 txt / 임시 파일 정리 / 짝수 크기
[3] 녹음 모드 (mp3 + 표식)
  ok   결과 ok
       2026.09.09., 09.57., 회의.mp3  streams=['audio']  dur=2.04
  ok   mp3 / 길이 2초 안팎 / 표식 2개 / 표식 csv 3줄 / 원본 WAV 보존
전부 통과

1.5초 녹화한 뒤 1초 일시정지하고 다시 1.5초 녹화한 결과가 3.03초 영상으로 나왔다. 이것이 4-2 의 박자 규칙이 맞다는 증거다.

7-2. 진짜 화면을 진짜 단추로

가짜 원천 시험은 엔진만 본다. 화면 캡처 경로(mss)와 창의 단추가 실제로 이어지는지는 따로 봐야 한다. scripts/realtest.py 는 0.1초마다 숫자가 오르는 「내용 창」을 띄우고, 프로그램 창의 「시작」「버전표시」「일시정지」「재개」「정지」 단추를 차례로 누른다. 마이크가 없는 PC 에서도 돌아야 하므로 소리는 끈다. 클라우드의 가상 X 화면(1280×800)에서 돌린 결과다.

  ok   시작 단추로 세션 시작        mic: None  system: None
  ok   마이크 없으면 소리 트랙 없이 진행
  ok   진짜 ScreenSource
  ok   표식 단추 / 일시정지 단추 / 일시정지 중 프레임 안 늘어남 / 재개
  ok   마무리 중엔 단추 잠김
       2026.09.09., 10.41., 실기.mp4  streams=['video']  dur=5.10  elapsed=5.10
  ok   길이 = 실제 녹화 시간(일시정지 제외)
  ok   1초 간격 정지 화면 5장 이상 / 정지 화면이 서로 다름
전부 통과      (30fps × 5.10초 = 153 프레임, 인코딩된 프레임 153)
녹화 결과 정지 화면
결과 MP4 에서 1초 간격으로 뽑은 정지 화면(1·3·5초). 내용 창의 숫자가 0019 → 0039 → 0073 으로 오르고, 프로그램 창의 시계도 00:00:00 → 02 → 04 로 함께 찍혔다. 3초와 5초 사이에 숫자가 34 오른 것은 그 사이에 1초 일시정지가 들어 있기 때문이다.

마이크가 없으면 소리 항목이 저절로 꺼지고 영상 트랙만 있는 MP4 가 나온다. 이 경우 ffmpeg 합치기 단계는 -c:v copy -an 으로 지나가므로 정지 뒤 기다림이 거의 없다.

8. 남은 일

  • Windows 실기. run0.bat 을 한 번 실행하면 설치, 시험, exe 빌드, 캡처, 진짜 화면 단추 시험(realtest), 실제 장치 3초 녹화가 차례로 돈다. 결과는 docs/verify/run0.log 에 남는다.
  • 시스템 소리. PortAudio 19.7 의 [Loopback] 장치가 잡히는지, 안 잡히면 PyAudioWPatch 경로가 도는지 확인한다.
  • 다음 판에서는 마우스 커서 덧그리기를 넣고, 배율(125%·150%) 화면에서 영역 좌표가 맞는지 확인한다.

2편. 소리가 0.15초 앞서 있었다 · v1.0.0.1

2026.09.09. 게시

목적

1판 코드를 처음부터 다시 읽어 시험이 잡지 못한 결함을 찾아 고친다. exe 를 클라우드에서 만들어 판마다 함께 낸다.

계획

  1. 값이 어디서 와서 어디로 가는지 따라가며 코드 점검
  2. 결함은 수치로 재현한 뒤 고치고, 그 수치를 재는 시험을 붙임
  3. 보완(단축키·영역·출력 크기·커서)은 고친 뒤 시험
  4. wine 에 Windows Python 을 올려 PyInstaller 빌드
  5. 빌드된 exe 로 실제 녹화

체크리스트 8/9

항목 상태 비고
결함 1: 소리가 영상보다 0.15초 앞섬 → atrim·adelay, 섬광·삐 소리 시험으로 1.000초 일치 확인 완료
결함 2: 버전표시 시각이 파일 시각과 다름 → 첫 프레임 기준으로 보정 완료
결함 3: 합치는 중 재시작하면 세션을 잃음 → finalizing 상태로 차단 완료
단축키 Ctrl+Alt 로 변경, settings.json 에서 수정 가능 완료
영역 화면 밖 잘라내기 + 미리보기 완료
출력 크기 50·75%, 마우스 커서 덧그리기 완료
exe 189MB 클라우드 빌드(icuuc.dll 대역, numpy 2.0.2, ffmpeg 한 벌) 완료
Windows Python 으로 enginetest·realtest 전부 통과, exe 로 5.93초 녹화 완료
실제 Windows 에서 loopback 장치·배율 화면 확인 미완

1. 점검 방법

1판의 시험은 결과 파일이 나오는지와 길이가 맞는지만 확인하였다. 이번에는 코드를 처음부터 다시 읽으면서 각 값이 어디서 와서 어디로 가는지를 따라갔다. 찾은 것은 결함 셋과 보완 넷이다. 결함은 수치로 재현한 뒤 고쳤고, 보완은 고친 뒤 시험을 붙였다.

# 구분 내용 재현·확인
1 결함 소리가 영상보다 0.15초 앞서 있음 enginetest [4] 섬광·삐 소리 시각 비교
2 결함 버전표시 시각이 파일 시각과 다름 enginetest [6]
3 결함 합치는 중 단축키로 시작하면 새 세션이 화면에서 사라짐 realtest「합치는 중엔 새로 시작 안 됨」
4 보완 Ctrl+Shift+R 이 브라우저 강력 새로고침과 겹침 Ctrl+Alt+R/P/M, 설정으로 변경
5 보완 영역이 화면 밖으로 나가면 mss 예외. 배율 어긋남을 알 길 없음 잘라내기 + 미리보기, realtest
6 보완 4K 화면을 그대로 넣으면 인코더가 못 따라감 출력 크기 50·75%, enginetest [5]
7 보완 커서가 안 찍힘 화살표 덧그리기, enginetest [5]

2. 결함 1. 소리가 0.15초 앞서 있었다

1판의 _audio_parts 는 소리 시작이 영상보다 늦은 경우(양수)만 -itsoffset 으로 처리하고, 이른 경우(음수)는 0으로 버렸다. 세션은 소리 장치를 먼저 열고 그 다음에 ffmpeg 를 띄운다. 따라서 소리가 항상 먼저 시작한다. 측정값은 다음과 같다.

t_start->video 0.175
t_start->mic   0.025
mic - video   -0.150   (음수 = 소리가 먼저. 1판은 이 값을 버렸다)

결과 파일에서 소리는 영상보다 0.15초 앞서 재생된다. 1판의 시험이 이것을 잡지 못한 이유는 길이만 쟀기 때문이다. 길이는 -shortest 가 맞추므로 항상 통과한다.

고침

세 가지를 바꿨다. 첫째, 음수면 소리 앞머리를 그만큼 잘라낸다(atrim). 둘째, 양수면 -itsoffset 대신 adelay 를 쓴다. amix 는 늦게 시작하는 입력 앞을 무음으로 채워 주지 않으므로 -itsoffset 은 섞을 때 어긋난다. 셋째, 결과 길이는 영상 길이로 확정한다. 영상 프레임 수 ÷ FPS 를 알고 있으니 apad=whole_dur 로 채우고 atrim=end 로 자른다.

def _audio_chain(idx, off, tag):
    chain = f"[{idx}:a]aresample=48000"
    if off > 0.0005:   chain += f",adelay={int(round(off * 1000))}:all=1"
    elif off < -0.0005: chain += f",atrim=start={-off:.3f},asetpts=PTS-STARTPTS"
    return chain + f"[{tag}]"

fit = f",apad=whole_dur={duration:.3f},atrim=end={duration:.3f}"

고치는 중에 ffmpeg 가 끝나지 않던 문제

처음에는 apad(무한)와 -shortest 를 함께 썼다. 영상을 다시 인코딩할 때는 동작하는 조합이지만 -c:v copy 와 함께 쓰면 ffmpeg 가 끝나지 않았다. 2분을 기다린 뒤 프로세스를 죽였다. 영상 길이를 숫자로 알고 있으므로 whole_dur 로 끊는 쪽이 맞다.

시험

길이가 아니라 소리와 영상의 맞춤을 재는 시험을 넣었다. 1.0초에 흰 프레임 3장이 있는 영상과, 소리 시계로 1.15초에 삐 소리가 있는 WAV(0.15초 일찍 켜진 상황)를 만들어 합친 뒤, 결과에서 삐 소리의 시작과 섬광의 시작을 따로 잰다.

[4] 영상·소리 맞춤 (소리가 0.15초 먼저 시작)
       삐 시작 1.000s / 섬광 시작 1.00s / 길이 2.00s
  ok   삐 소리가 1.00초에
  ok   섬광이 1.00초에
  ok   길이 = 영상 길이 2.0

3. 결함 2. 버전표시 시각

버전표시는 세션 시계(_t_start)로 쟀다. 파일의 0초는 첫 프레임을 보낸 순간이라 그보다 0.02~0.5초 뒤다. 플레이어에서 버전표시 시각으로 가면 그만큼 앞이다. 마무리할 때 media_start() − _t_start 만큼 빼서 적는다. 녹음 모드는 가장 먼저 블록이 온 시각이 기준이다. 두 소리 원천의 시작 차이도 같은 기준으로 adelay 한다.

4. 결함 3. 합치는 중에 다시 시작

정지를 누르면 화면의 단추는 잠기지만 단축키는 살아 있다. 그 사이에 Ctrl+Shift+R 을 누르면 session.running 이 이미 False 라 새 세션이 만들어지고, 조금 뒤 앞 세션의 마무리 신호가 self.session = None 을 해 버린다. 새 세션은 돌고 있는데 화면에는 그 세션이 없으므로 정지할 수 없다.

finalizing 을 따로 두고, 그것이 남아 있으면 시작을 거부하고 상태줄에 이유를 쓴다. 마무리 신호는 자기 세션이 아닌 것을 지우지 않는다. realtest 에서 정지 직후 start() 를 다시 불러 확인한다.

5. 보완

5-1. 단축키

Ctrl+Shift+R 은 Chrome·Edge 의 강력 새로고침이다. 전역 단축키는 다른 프로그램에 등록된 같은 조합보다 우선하므로, 브라우저에서 새로고침을 누를 때마다 녹화가 켜진다. Ctrl+Alt+R/P/M 으로 바꾸고 settings.json 에서 고칠 수 있게 했다. “F9”, “Ctrl+Shift+F12” 같은 글을 읽어 RegisterHotKey 의 modifier·vk 로 바꾸는 parse() 를 넣었다.

5-2. 영역: 잘라내기와 미리보기

영역을 화면 밖까지 끌면 mss 가 예외를 낸다. 가상 데스크톱 사각형으로 잘라낸다. 그리고 고른 직후 그 자리를 한 번 찍어 창 안에 작은 그림으로 표시한다. Windows 배율 125%·150% 에서 좌표가 어긋나면 이 그림이 어긋난 자리를 보여 줄 것이다. 배율 문제를 클라우드에서는 재현할 수 없으니, 사용자가 눈으로 확인할 자리를 만든 것이다.

영역 미리보기
realtest 가 (−50,−20) 500×300 을 넣었을 때. (0,0) 450×280 으로 잘리고 미리보기가 찍혔다.

5-3. 출력 크기와 커서

4K 화면은 프레임 하나가 33MB 다. 30fps 면 초당 1GB 를 파이프로 넘기고 libx264 가 그것을 따라가야 한다. 출력 크기 50%·75% 설정을 두어 ffmpeg 의 scale 로 줄인다. 커서는 mss 가 찍지 않으므로 Windows GetCursorPos 위치에 화살표 하나를 numpy 로 덧그린다. 실제 커서 그림을 뽑는 대신 흰 테두리·검은 속의 화살표 하나로 통일했다.

v1.0.0.1 녹화 모드
v1.0.0.1 녹화 모드. 원천 옆에 미리보기, 화질에 출력 크기와 커서.

6. 그 밖에 고친 것

  • 일시정지 표시의 ⏸ 글리프가 Consolas 에 없어 네모로 나왔다. 글리프 대신 숫자 색을 회색으로 바꿔 표시한다.
  • 품질 콤보가 잘려 「보통 (CRF」까지만 보였다. 화질 묶음을 두 줄로 나눴다.
  • 녹화 모드와 녹음 모드가 장치 선택을 한 자리에 저장해 모드를 바꾸면 선택이 사라졌다. 모드마다 따로 저장한다.
  • 창을 닫으면 트레이로 내려가는데 녹화가 계속되는지 알 수 없었다. 트레이 알림을 한 번 띄운다.
  • 시험 스크립트가 사용자의 설정 파일(저장 폴더)을 덮어썼다. 시험은 임시 설정 파일을 쓴다.
  • capture.py 의 processEvents() 가 다음 단계 타이머를 먼저 돌려 한 단계 앞선 화면이 찍혔다. 그 호출을 제거했다.

7. 시험 결과

enginetest  [1] 파일 이름 · [2] 녹화 · [3] 녹음 · [4] 맞춤 · [5] 커서·크기 · [6] 표식   전부 통과
realtest    화면 밖 영역 잘라냄 · 미리보기 · 시작 · 표식 · 일시정지 · 재개 · 합치는 중 재시작 차단
            · 길이 = 경과 시간 · 정지 화면 서로 다름 · 세션 정리                       전부 통과
realtest 정지 화면
v1.0.0.1 realtest 의 1·3·5초 정지 화면.

8. exe 를 클라우드에서 만들다

1판은 exe 를 사용자 PC 의 run0.bat 에 맡겼다. 이번에는 클라우드에서 만들어 넣는다. wine 9.0 에 64비트 Windows Python 3.11.9(NuGet 배포본)를 올렸다. 그 위에 PySide6·mss·sounddevice·numpy·imageio-ffmpeg·PyInstaller 를 Windows 휠로 설치했다. 막힌 곳이 둘이었다.

8-1. icuuc.dll 이 없다

Qt6Core.dll 이 icuuc.dll 을 정적으로 끌어온다. Windows 10 부터 System32 에 들어 있는 시스템 ICU 라 실제 PC 에서는 문제가 없지만 wine 에는 없다. PyInstaller 의 PySide6 훅은 QtCore 를 실제로 import 해 경로를 묻기 때문에 이것이 안 뜨면 빌드가 깨진다. Qt6Core 가 쓰는 함수를 objdump 로 세어 보니 ucnv_* 스무 개다. 그 이름만 내보내고 전부 실패 값을 돌려주는 대역 DLL 을 mingw 로 만들어 wine 의 system32 에 넣었다. Qt 는 ICU 코덱이 없으면 자체 코덱으로 간다.

API void* ucnv_open(const char* n, UErrorCode* e){ if(e) *e = 4; return NULL; }
API int   ucnv_countAvailable(void){ return 0; }
...  /* 20개, 빌드 전용. 배포본에는 안 들어간다 */

8-2. numpy 2.4 가 wine 에서 안 뜬다

ucrtbase.dll.crealf 가 wine 9.0 에 구현돼 있지 않다. 빌드 환경만 numpy 2.0.2 로 내렸다. 프로그램의 요구는 1.26 이상이라 상관없다.

8-3. 두 벌 들어간 ffmpeg

첫 빌드가 273MB 였다. PyInstaller 훅이 imageio-ffmpeg 의 바이너리(84MB)를 넣고, build.bat 이 exe 옆에 또 복사했다. 스펙에서 훅이 넣는 것을 빼고 _internal/ffmpeg.exe 한 벌만 두었다. 안 쓰는 Qt 파일(소프트웨어 OpenGL 20MB, 번역 6.7MB)도 뺐다. 결과는 189MB 다.

8-4. 한글 파일 이름

Windows Python 으로 enginetest 를 돌리니 회의.mic.tmp.wav 를 못 열었다. wine 의 win32 파일계통이 한글 경로를 못 받는 것이라 실제 Windows 에서는 없는 일이지만, 덕분에 구조를 고쳤다. 임시 파일은 gr_시각_pid.* 같은 ASCII 이름으로 쓰고 마지막에 os.replace 로 최종 이름을 준다. 그것마저 안 되면 주석을 뺀 이름으로 물러선다. ffmpeg 와 wave 에 한글 경로를 직접 주는 자리가 없어졌다.

8-5. exe 로 실제 녹화

Windows Python 으로 enginetest 6묶음과 realtest 20항목이 전부 통과했다. 빌드된 exe 는 가상 화면에 띄워 xdotool 로 시작·커서 이동·버전표시·정지를 눌러 확인했다. 5.93초 MP4 와 버전표시 파일이 나왔고, 정지 화면에 덧그린 커서 화살표가 찍혀 있다.

exe 로 녹화한 정지 화면
GenealogyRecording_v1.0.0.1.exe 가 찍은 프레임(2초 지점). 「마우스 커서 그리기」 글자 옆에 덧그린 화살표가 보인다. wine 이라 한글 파일 이름은 ASCII 로 물러섰다.

9. 남은 일

  • Windows 실기. exe 를 바로 실행해 WASAPI loopback 장치가 잡히는지와 배율 화면의 영역 미리보기가 맞는지 확인한다. 다시 빌드하려면 run1.bat 을 쓴다.
  • 커서 위치는 Windows GetCursorPos 로 얻는다. wine 에서는 잡혔고, 실제 PC 의 배율 화면에서 자리가 맞는지 확인한다.

3편. 기존 것보다 나쁘지는 않아야 한다 · v1.0.0.2

2026.09.10. 게시

목적

기존 녹화·녹음 프로그램에는 있는데 이 프로그램에는 없는 기능을 세어 채운다. 기존 프로그램보다 못하지 않은 상태를 이 판의 목표로 한다.

계획

  1. 기존 녹화·녹음 프로그램 셋의 기본 기능을 표로 늘어놓고 빠진 것 표시
  2. 넣을 것 열둘과 넣지 않을 것 셋을 이유와 함께 정함
  3. 창 녹화·캡처 제외·미니 막대·초 읽기·자동 정지·클릭 강조·스크린샷·하드웨어 인코더·디스크·파일 크기·최근 목록·비트레이트·프리셋 구현
  4. enginetest [7] 과 realtest 를 새 기능에 맞게 확장
  5. wine 에서 Windows Python 시험과 exe 실기

체크리스트 8/10

항목 상태 비고
기능 비교표(18항목) 완료
창 녹화: EnumWindows 목록, 프레임마다 창 위치 따라가기 완료
자기 창·미니 막대 캡처 제외(SetWindowDisplayAffinity) 완료
미니 제어 막대, 초 읽기, 자동 정지 완료
클릭 강조, 스크린샷 Ctrl+Alt+S 완료
하드웨어 인코더 자동 탐지(뒤 스레드), 디스크 여유, 파일 크기, 최근 목록, 비트레이트, 프리셋 완료
결함 수정: 느린 PC 에서 일시정지 직후 프레임 7장 더 들어감 완료
enginetest 7묶음·realtest 클라우드와 wine 전부 통과, exe 실기 완료
실제 Windows 에서 창 목록·캡처 제외·클릭 강조·하드웨어 인코더 확인 미완 wine 은 반쪽만 보여 줌
녹화 중 그리기(펜), 웹캠 미완 다음 판

1. 기준

이 판의 기준은 기존 프로그램보다 못하지 않은 것이다. 기존 녹화 프로그램 둘(A 는 유료, B 는 무료 방송용)과 기존 녹음 프로그램 하나의 기본 기능을 표로 늘어놓고, 빠진 것을 하나씩 채웠다. 넣지 않은 것은 이유를 적었다.

기능 기존 녹화 프로그램 A
(유료)
기존 녹화 프로그램 B
(무료)
기존 녹음 프로그램 A
(무료)
v1.0.0.1 v1.0.0.2
특정 창 녹화(따라가기) O O – X O EnumWindows + 매 프레임 창 위치
자기 창이 영상에 안 찍힘 O O – X(트레이로 숨김) O SetWindowDisplayAffinity
녹화 중 작은 제어 막대 O △(독) – X O 미니 막대, 끌어서 이동
시작 전 초 읽기 O X X X O 0·3·5초
정해진 시간 뒤 자동 정지 O X X X O 10~120분
마우스 클릭 효과 O X – X O 노란 고리
스크린샷 O O – X O Ctrl+Alt+S, 같은 이름 규칙
하드웨어 인코더 O O – X O NVENC·QSV·AMF 자동 탐지
디스크 여유 확인 O O – X O 500MB 미만이면 시작 거부
녹화 중 파일 크기 표시 O O – X O
최근 결과 목록 유지 O – O X(끄면 사라짐) O 설정에 20개
소리 비트레이트 O O O X(160k 고정) O 96~256k
영역 크기 프리셋 O X – X O HD·FHD·480
버전표시(marker) 파일로 저장 X X △(앱 안) O O
화면 녹화 O O X O O
음성 녹음 X X O O O
웹캠 덧붙이기 O O – X X 카메라가 없어 시험할 수 없음
방송·장면 전환 X O – X X 목적 밖
녹화 중 그리기(펜) O X – X X 다음 판

2. 창 녹화

원천 선택에 모니터와 영역 다음으로 창을 추가하였다. Windows 의 EnumWindows 로 제목이 있고 보이는 최상위 창을 모으고, DwmGetWindowAttribute(EXTENDED_FRAME_BOUNDS) 로 그림자를 뺀 실제 사각형을 얻는다. 시작할 때 창 크기를 출력 크기로 고정하고, 프레임마다 창의 지금 위치를 다시 물어 그 자리를 찍는다. 인코더는 크기가 바뀌면 안 되므로 창이 작아지면 주변이 함께 찍히고 커지면 왼쪽 위부터 고정 크기만 찍힌다. 창이 화면 밖으로 나가면 사각형을 안으로 밀고, 최소화되거나 닫히면 예외를 내서 VideoWriter 가 직전 프레임을 다시 쓴다.

class FollowSource:
    def _place(self):
        r = self.provider()                 # 지금 창 사각형. 없으면 None
        if r is None: raise RuntimeError("창이 보이지 않는다")
        left = max(b.left, min(r.left, b.left + b.width - self.rect.width))   # 화면 안으로
        ...
창 따라가기
realtest 가 사각형을 1초마다 (0,0)→(300,200)→(700,400) 으로 옮기며 찍은 세 프레임. 자리마다 다른 화면이 잡혔다.

3. 자기 창을 영상에서 빼기와 미니 막대

1판은 녹화가 시작되면 창을 트레이로 숨겼다. 그러면 정지하려고 트레이를 찾아야 한다. 이번에는 SetWindowDisplayAffinity(hwnd, WDA_EXCLUDEFROMCAPTURE) 를 건다. Windows 10 2004 부터 있는 기능으로, 창은 모니터에는 보이지만 어떤 화면 캡처에도 찍히지 않는다. 주 창과 미니 막대 둘 다 이것을 건다. 미니 막대는 시간·파일 크기·일시정지·버전표시·정지·창 보기가 든 작은 막대다. 끌어서 옮길 수 있고 늘 위에 있다.

미니 막대
exe 가 wine 에서 찍은 프레임의 오른쪽 아래. wine 은 캡처 제외를 지원하지 않아 막대가 찍혔다. 실제 Windows 10 2004 이상에서는 안 찍힌다.

4. 나머지

  • 초 읽기. 시작을 누르면 화면 가운데 큰 숫자가 3·2·1 로 줄고 그 뒤에 시작한다. Esc 로 취소한다. 녹화 전에 창을 정리할 시간을 두기 위한 것이다.
  • 자동 정지. 10·30·60·120분 가운데 고른다. 회의 시간이 정해져 있을 때 정지를 잊어도 그 시간에 멈춘다.
  • 클릭 강조. GetAsyncKeyState(VK_LBUTTON) 이 눌려 있는 프레임에 커서 끝에 노란 고리(반지름 18, 두께 5)를 알파 합성한다.
  • 스크린샷. Ctrl+Alt+S 를 누르면 지금 고른 원천을 PNG 한 장으로 저장한다. 녹화 중이 아니어도 되고, 이름 규칙은 같다.
  • 하드웨어 인코더. -encoders 목록에 있어도 드라이버가 없으면 못 돈다. 64×64 두 프레임을 실제로 넣어 보고 되는 것을 쓴다. NVENC 는 -rc vbr -cq, QSV 는 -global_quality, AMF 는 -rc cqp. 창이 뜨자마자 뒤에서 확인한다(아래 6절).
  • 디스크·파일 크기. 저장 폴더 여유가 500MB 미만이면 시작을 거부하고, 2GB 미만이면 노란색으로 표시한다. 녹화 중 임시 파일 크기를 1초마다 표시한다.
  • 최근 결과·비트레이트·프리셋. 최근 목록을 설정에 20개까지 저장한다. 소리 비트레이트는 96~256 kbps 에서 고른다. 영역 프리셋은 고른 모니터 가운데에 그 크기를 잡는다.
v1.0.0.2 녹화 모드
v1.0.0.2 녹화 모드. 원천에 「창」, 화질에 클릭 강조·인코더, 저장에 미니 막대·시작 전·자동 정지·스크린샷·여유 공간.

5. 느린 PC 에서 일시정지 직후 프레임이 더 들어가던 결함

wine 에서 realtest 를 돌리니 일시정지 중에 프레임이 늘지 않는지 보는 항목이 7장 차이로 실패했다. wine 의 화면 캡처는 한 장에 100ms 넘게 걸린다. 캡처 스레드는 늦은 만큼 같은 프레임을 다시 보내 박자를 맞추는데(1판 4-2), 그 채우기 고리가 일시정지 신호를 안 봤다. 일시정지를 누른 뒤에도 밀린 박자를 최대 fps 장까지 채우고 나서야 멈췄다. 빠른 PC 에서는 밀린 박자가 0~1 이라 드러나지 않는다.

for _ in range(fill):
    if self._pause_ev.is_set() or self._stop_ev.is_set():
        break                              # 채우다가도 일시정지면 그만
    pipe.write(frame); tick += 1

같은 자리에서 하나를 더 정했다. 밀린 박자가 3초(fps × 3)를 넘으면 그 PC 는 이 설정을 못 따라가는 것이다. 무한히 채우면 파일만 커지고 실시간과도 어긋난다. 넘친 만큼은 버리고 시계를 다시 맞추되, ticks_lost 에 세어 두었다가 끝날 때 상태줄에 「PC 가 못 따라가 N초를 놓쳤다. 초당 프레임이나 출력 크기를 낮추면 좋다」고 알린다.

6. 첫 시작이 5초 멈추던 것

하드웨어 인코더 확인은 ffmpeg 를 세 번 띄운다. 처음엔 시작 단추 안에서 했더니 wine 에서 단추가 5초 멈췄고, 초 읽기가 그 뒤에야 시작됐다. 실제 PC 에서도 1~3초는 멈춘다. 창이 뜨자마자 뒤 스레드에서 확인하게 옮기고, 시작 때 아직 안 끝났으면 1초만 기다리고 CPU 인코더로 간다. 다음 시작부터는 결과가 있다.

7. 시험

enginetest  [1]~[6] 이전 판 그대로 + [7] 클릭 고리 · 인코더 인수 · 하드웨어 탐지 · 창 따라가기(옮김·화면 밖·사라짐) · 파일 크기 · 96k
            클라우드 Linux 전부 통과 / Windows Python(wine) 전부 통과
realtest    스크린샷 → 3초 초 읽기 → 시작 → 미니 막대 → 표식 → 미니 막대로 일시정지·재개 → 자동 정지(1.5초로 앞당김)
            → 결과 검증 → 창 따라가기 3위치       클라우드 전부 통과 / wine 전부 통과
exe         wine 에서 스크린샷 단추 → 초 읽기 → 녹화 → 정지. PNG 와 3.03초 MP4
초 읽기
exe 의 초 읽기. 화면 가운데 「1」.

8. 남은 일

  • 실제 Windows 에서 창 목록, 캡처 제외, 클릭 강조, 하드웨어 인코더가 잡히는지 확인한다. wine 에서는 넷 다 일부만 동작한다(창 목록 없음, 캡처 제외 무시, 인코더 없음).
  • 녹화 중 그리기(펜)와 웹캠은 다음 판에서 다룬다.

4편. 핵심기능 아홉 가지를 정한다 · v1.0.1.0 계획

2026.09.29. 게시

목적

앞으로 만들 기능의 우선순위를 정한다. 본편에 실을 핵심기능 아홉 가지를 정하고, 판마다 무엇을 넣을지 배정한다.

계획

  1. 후보 기능을 빠짐없이 늘어놓는다
  2. 고르는 기준 세 가지를 세운다
  3. 기준으로 후보를 판정해 아홉을 남긴다
  4. 남긴 아홉을 판에 배정한다
  5. 장치 없는 환경에서 각 기능을 어떻게 시험할지 적는다

체크리스트 5/7

항목 상태 비고
후보 열여섯 가지 정리 완료
기준 셋(쓰임, 기본기, 시험 가능성) 완료
핵심기능 아홉 확정안 완료
판 배정안(v1.0.1.0~v1.2.0.0) 완료
기능별 시험 방법 완료
확정안에 대한 결정 미완 사용자 판단 대기
본편 핵심기능 절을 아홉으로 다시 쓰기 미완 확정 뒤

1. 왜 아홉인가

1판부터 3판까지는 있어야 할 기능을 채우는 순서로 만들었다. 1판은 녹화와 녹음을 동작하게 하였고, 2판은 소리와 영상이 어긋나는 결함을 고쳤고, 3판은 기존 녹화·녹음 프로그램에 있는 기본 기능을 세어 채웠다. 그 결과 기능이 열여덟 항목이 되었고, 다음에 무엇을 만들지가 정해져 있지 않다.

본편 화면은 핵심기능을 3열 카드로 그린다. 지금 본편에는 일곱 개가 있어 마지막 줄이 비어 있다. 아홉을 채우면 3×3 이 된다. 칸을 채우기 위해 아홉을 고르는 것이 아니라, 아홉이라는 수를 정해 두면 무엇이 핵심이고 무엇이 부수적인지를 가르는 기준이 필요해진다. 이 회차에서는 그 기준을 세우고 후보를 판정한다.

2. 후보

세 판에 이미 들어간 것과 개발일지의 「남은 일」에 적어 둔 것, 그리고 이 프로그램의 쓰임에서 나오는 것을 모두 늘어놓았다. 열여섯이다.

번호 후보 어디서 나왔나 지금 상태
1 화면 녹화(모니터·영역) 1판 있음
2 창 녹화(따라가기) 3판 있음
3 음성 녹음(마이크·시스템 소리) 1판 있음
4 버전표시(marker) 파일 저장 1판 있음
5 파일 이름 규칙 1판 있음
6 미니 제어 막대·자기 창 제외·초 읽기·자동 정지 3판 있음
7 클릭 강조·마우스 커서 2판, 3판 있음
8 하드웨어 인코더 자동 탐지 3판 있음
9 스크린샷 3판 있음
10 예약 녹화(정한 시각에 시작·정지) 회의 시간표에서 나온 요구 없음
11 회의 전사(음성을 글로) 1판의 「왜 만드는가」 없음
12 녹화 중 그리기(펜) 3판 「남은 일」 없음
13 자르기와 내보내기(구간 자르기, MP3 추출, GIF) 버전표시의 쓰임에서 나온 요구 없음
14 버전표시를 MP4 챕터로 넣기 4번의 확장 없음
15 웹캠 덧붙이기 3판 비교표 없음
16 방송 송출·장면 전환 3판 비교표 없음

3. 기준

세 가지 기준으로 판정하였다. 세 기준을 모두 만족하는 것만 핵심기능에 둔다.

첫째, 쓰임에 닿는가. 이 프로그램의 쓰임은 강의 기록과 회의 전사다. 1판에서 직접 만들기로 한 이유가 파일 이름 규칙과 버전표시였고, 둘 다 회의를 기록한 뒤 전사하는 일에서 나왔다. 기능이 이 쓰임에 직접 닿지 않으면 핵심이 아니다.

둘째, 기본기인가. 3판의 기준은 기존 프로그램보다 못하지 않은 것이었다. 기존 녹화·녹음 프로그램의 사용자가 당연히 기대하는 것은 핵심에 두고, 있으면 좋은 것은 주요기능 표에 둔다.

셋째, 시험할 수 있는가. 개발 환경에는 카메라와 마이크가 없다. 1판부터 가짜 화면과 사인파로 엔진을 시험해 왔다. 장치 없이 시험할 방법이 없는 기능은 만들어도 확인할 수 없으므로 핵심에 두지 않는다.

4. 판정

후보 쓰임 기본기 시험 판정 사유
1 화면 녹화 O O O 핵심 프로그램의 절반이다
2 창 녹화 O O O 핵심(1과 합침) 원천의 한 종류이므로 화면 녹화 한 칸에 넣는다
3 음성 녹음 O O O 핵심 프로그램의 나머지 절반이다
4 버전표시 O X O 핵심 기존 프로그램에 없지만 이 프로그램을 만든 이유다. 기본기 기준의 예외로 둔다
5 파일 이름 규칙 O X O 핵심 4와 같은 이유다
6 녹화 중 제어 O O O 핵심 미니 막대, 단축키, 초 읽기, 자동 정지, 자기 창 제외를 한 칸으로 묶는다
7 클릭 강조·커서 △ O O 주요기능 강의 녹화에 쓰이지만 없어도 기록은 된다
8 하드웨어 인코더 △ O △ 주요기능 있으면 가볍지만 결과물이 달라지지 않는다. 실제 GPU 없이는 시험이 반쪽이다
9 스크린샷 △ O O 주요기능 부수 기능이다
10 예약 녹화 O O O 핵심 회의 시간표대로 자리를 비워도 기록이 남는다. 시계만 있으면 시험된다
11 회의 전사 O X O 핵심 쓰임의 끝이 전사다. 시험은 합성 음성 파일로 한다
12 그리기(펜) O △ O 핵심 강의 녹화의 판서다. 마우스 이동을 흉내 내어 시험한다
13 자르기·내보내기 O △ O 핵심 버전표시 구간으로 자르는 것이 전사와 이어진다. ffmpeg 만으로 시험된다
14 MP4 챕터 O X O 핵심(4에 합침) 버전표시 칸의 확장이다
15 웹캠 △ O X 제외 카메라가 없어 시험할 수 없다
16 방송·장면 전환 X X X 제외 목적 밖이다

기본기 기준에 예외를 둔 것은 4번과 5번이다. 두 기능은 기존 프로그램에 없어서 기본기가 아니지만, 이 프로그램을 만든 이유이므로 핵심에서 뺄 수 없다. 기준을 세 가지로 두되 「만든 이유」는 기준보다 앞에 둔다.

5. 핵심기능 아홉

번호 핵심기능 하는 일 상태
1 화면 녹화 모니터 전체, 끌어서 고른 영역, 특정 창(움직여도 따라감)을 MP4 로 기록한다 있음
2 음성 녹음 마이크와 시스템 소리를 함께 MP3·M4A·WAV 로 기록한다 있음
3 버전표시(marker) 녹화·녹음 중 단축키로 시각과 메모를 찍고 결과 파일 곁에 txt·csv 로 남긴다. MP4 챕터로도 넣는다 있음, 챕터는 다음 판
4 파일 이름 규칙 연도(0000).월(00).일(00)., 시간(00).분(00)., 주석.확장자 로 저장한다 있음
5 녹화 중 제어 미니 제어 막대, 전역 단축키, 초 읽기, 자동 정지, 자기 창 제외 있음
6 예약 녹화 정한 시각에 시작하고 정한 시각에 멈춘다 다음 판
7 회의 전사 녹음 파일을 PC 안에서 음성 인식으로 글로 바꾸고, 버전표시 시각을 전사문에 표시로 끼운다. 소리를 밖으로 보내지 않는다 다음 판
8 그리기와 강조 녹화 중 화면 위에 펜으로 판서하고, 클릭 강조를 확장한다 다음 판
9 자르기와 내보내기 버전표시 구간으로 잘라내고, MP4 에서 MP3 를 뽑고, 짧은 구간을 GIF 로 만든다. 다시 인코딩하지 않는다 다음 판

6. 판 배정

네 자리 판 번호에서 셋째 자리를 기능 추가에 쓴다. 한 판에 핵심기능 하나를 넣는다. 전사는 음성 인식 모델 파일이 커서 실행 파일과 따로 내려받게 해야 하므로 뒤에 둔다.

판 넣는 것 함께 넣는 것
v1.0.1.0 예약 녹화 버전표시를 MP4 챕터로
v1.0.2.0 자르기와 내보내기
v1.1.0.0 회의 전사 모델 파일 내려받기 안내
v1.2.0.0 그리기와 강조

7. 시험 방법

장치가 없는 환경에서 각 기능을 확인하는 방법을 미리 적어 둔다. 시험 방법이 없는 기능은 만들지 않는다.

기능 시험 방법
예약 녹화 시계를 가짜로 바꿔 예약 시각을 몇 초 뒤로 두고, 시작·정지 시각이 예약과 1초 안에 맞는지 잰다
MP4 챕터 버전표시 세 개를 찍은 결과를 ffprobe 로 읽어 챕터 수와 시각이 같은지 본다
자르기·내보내기 enginetest 의 3초 영상을 버전표시 구간으로 잘라 길이를 재고, MP3 추출과 GIF 의 스트림을 ffprobe 로 확인한다
회의 전사 글을 합성 음성으로 읽힌 WAV 를 넣어 전사문이 원문과 얼마나 같은지(문자 오류율)를 잰다
그리기와 강조 가짜 마우스 이동을 넣어 프레임에 선이 그려지는지 화소를 센다

8. 남은 결정

아홉 가지 확정안과 판 배정안은 사용자의 결정을 기다린다. 결정되면 본편의 핵심기능 절을 아홉으로 다시 쓰고, 다음 판의 폴더를 만들어 예약 녹화부터 시작한다.

5편. 후보를 쉰아홉까지 세고 이름을 CatchCatch 로 정한다 · v1.0.1.0 계획

2026.09.30. 게시

목적

기존 프로그램이 가진 기능을 빠짐없이 세어, 4편의 아홉 밖에 무엇이 더 핵심이어야 하는지를 판정한다. 다음 판의 이름을 정한다.

계획

  1. 기존 프로그램 스물일곱 가지의 기능을 공식 문서로 조사한다
  2. 갈래별 비교표를 만든다
  3. 새 후보를 네 기준으로 판정한다
  4. 사용자가 더한 후보를 표에 올린다
  5. 다음 판의 이름을 정한다

체크리스트 6/8

항목 상태 비고
스물일곱 가지 조사(출처 291건) 완료
갈래별 비교표 일곱 완료
넷째 기준 추가 완료
새 후보 35개 판정 완료
사용자 요청 후보 8개 등록 완료
이름 변경 방침 완료
핵심기능 최종 결정 미완 사용자 판단 대기
본편 핵심기능·주요기능 절 작성 미완 결정 뒤

1. 왜 다시 세는가

4편에서 후보 열여섯을 세 기준으로 판정해 핵심기능 아홉을 정하였다. 후보는 세 판에 이미 들어간 것과 개발일지의 「남은 일」에서 나왔다. 기존 프로그램이 무엇을 갖추었는지는 3판의 비교표 세 가지에만 기대었다. 세 가지로는 부족하다. 회의 기록기가 갖추어야 할 기본기를 놓쳤을 수 있고, 이 프로그램만의 것이라고 여긴 기능이 다른 곳에 이미 있을 수 있다.

이 회차에서는 기존 프로그램을 스물일곱 가지로 넓혀 기능을 세었다. 판정 기준에 하나를 더하였고, 후보를 쉰아홉까지 늘렸다. 코드는 쓰지 않는다.

2. 조사 방법

조사 대상은 네 갈래다. 화면 녹화기 열한 가지다. 음성 녹음기·편집기 다섯 가지와 잡음 억제 기술 여섯 가지다. 회의 전사 서비스 아홉 가지와 PC 안에서 도는 음성인식 엔진 여덟 가지다. 화자 분리 도구 세 가지다. 무료와 유료, 운영체제 내장 기능을 함께 넣었다.

근거는 제조사의 공식 도움말, 판 이력, 가격 페이지, 운영체제 개발 문서, ffmpeg 문서로 한정하였다. 문서에 없는 기본값은 공개 저장소의 소스 코드로 확인하였다. 공식 문서가 스크립트로만 그려지거나 접근이 막힌 경우에만 제3자 자료를 쓰고 그 사실을 표시하였다. 문서에 없는 항목은 「문서에 없음」으로 두고 추정하지 않았다. 출처는 291건이며 조회일은 2026년 9월 29일이다. 표와 출처 목록은 별도 문서 「핵심기능 확장안」에 있다.

등급 무엇 쓰임새
1차 공식 도움말·매뉴얼·판 이력·가격 페이지, 운영체제 개발 문서, ffmpeg 문서 기능 유무와 수치
소스 공개 저장소의 소스 코드·리소스 파일 문서에 없는 기본값
2차 포럼·리뷰 1차가 막힌 경우에만, 표시하여 사용

3. 무엇을 보았는가

스물일곱 가지는 세 갈래로 나뉜다. 녹화기, 편집기, 전사·공유기다. 녹화와 한국어 전사를 한 프로그램이 하는 것은 셋뿐이고, 셋 다 전사의 처리 위치를 PC 안이라고 밝히지 않는다. 국내 전사 서비스 네 가지는 모두 서버에서 처리한다. 운영체제에 내장된 한국어 음성 인식은 화면 자막 기능 하나뿐이며 파일로 저장되지 않는다. PC 안에서 끝나는 한국어 회의 전사는 비어 있는 자리다.

녹화 중 마커는 이 프로그램만의 것이 아니다. 유료 녹화·편집기 하나는 녹화 중 단축키로 마커를 찍고, 무료 녹화·방송기 하나는 최근 판부터 챕터 마커 단축키를 둔다. 차이는 세 가지다. 첫째, 메모 글을 함께 찍는 것은 전사 서비스에만 있고 녹화기에는 없다. 둘째, 그 녹화·방송기의 챕터는 파일을 닫을 때 기록되므로 비정상 종료 시 사라진다. 이 프로그램은 찍는 즉시 txt·csv 곁파일에 쓴다. 셋째, 음성 편집기의 라벨은 오디오 파일 안에 넣을 수 없다. 이 프로그램의 MP4 챕터 계획이 그 공백을 메운다.

파일 이름은 서식 변수를 주는 프로그램이 둘 있고, 앱 이름·날짜·시각을 고정하는 내장 기능이 하나 있다. 날짜·시각·주석의 고정 규칙에 주석 입력을 결합한 것은 없다.

긴 기록을 지키는 기능은 흔하다. 유료 녹화기 하나는 시간·용량·무음 기준으로 녹화를 마치고 새 녹화를 시작한다. 무료 녹화·방송기는 시간·용량 분할과, 쓰는 도중에도 읽히는 조각 방식의 MP4 를 갖는다. 유료 녹화기는 색인 파일로 파손된 MP4 를 복구하고, 음성 편집기는 주기 스냅샷으로 복구한다. 이 프로그램에는 넷 다 없다.

마이크와 시스템 소리를 다른 트랙으로 저장하는 것은 넷에 있다. 전사 때 마이크 트랙만 넣으면 자기 발화와 회의 상대의 소리가 나뉜다. 화자 분리 모델 없이 두 화자를 가르는 길이다.

소리 처리는 녹화기 넷에 잡음 억제가 있고, 음성 편집기는 무음 탐지·무음 절단·음량 정규화를 모두 갖는다. CPU 에서 도는 공개 잡음 억제 구현이 셋 있다. 이 프로그램은 소리 처리가 비어 있다.

특정 프로그램의 소리만 잡는 기능은 둘에 있다. 운영체제 API 가 있으나 ffmpeg 와 흔한 Python 라이브러리가 지원하지 않아 직접 호출해야 한다.

전사 뒤에는 다섯이 따라온다. 자막 파일, 검색, 사용자 사전, 화자 분리, 요약이다. 요약만이 언어 모델을 요구한다.

클라우드 업로드, 공유 링크, 서버 전사, 서버 요약은 소리와 글을 PC 밖으로 보낸다. 무료판은 5분 제한, 편 수 제한, 로고 삽입 가운데 하나를 둔다. 이 프로그램은 제한이 없다.

4. 넷째 기준

4편의 세 기준(쓰임, 기본기, 시험 가능성)에 하나를 더한다. 넷째, PC 안에서 끝나는가. 소리·화면·전사문을 외부 서버로 보내야 동작하는 기능은 핵심에 두지 않는다. 회의 기록의 비밀 유지가 이 프로그램을 직접 만든 이유 가운데 하나이고, PC 안 처리는 장치 없는 환경에서도 시험이 된다. 요약처럼 언어 모델이 필요한 기능은 자매 소프트웨어와의 연계로 돌린다.

5. 새 후보와 판정

4편의 16번 다음부터 번호를 이었다. 열일곱부터 쉰하나까지 서른다섯이다. 핵심 후보만 표에 적고, 나머지는 판정만 적는다.

번호 후보 쓰임 기본기 시험 PC 안 판정
17 잡음 억제·음량 고르기 O O O O 핵심(10)
18 무음 구간 표시·제거 O △ O O 핵심(10에 합침)
19 음량 미터·입력 감시 O O O O 핵심(10에 합침)
20 시간·용량별 자동 분할 O △ O O 핵심(11)
21 비정상 종료 복구 O △ O O 핵심(11에 합침)
22 마이크·시스템 소리 트랙 분리 저장 O △ O O 핵심(11에 합침)
23 디스크 여유 감시 O △ O O 핵심(11에 합침)
24 자막 파일(SRT·VTT) 내보내기 O O O O 핵심(12)
25 화자 분리 O △ △ O 핵심(12에 합침, 뒤 순위)
26 전사문 검색과 시각 이동 O △ O O 핵심(12에 합침)
27 사용자 사전(고유명사) O X O O 핵심(12에 합침)
28 외부 녹음 파일 불러와 전사 O O O O 핵심(7에 합침)
51 절전 해제 예약 녹화 O △ △ O 핵심(6에 합침)

주요기능으로 둔 것은 열넷이다. 실시간 전사, 특정 프로그램 소리만 녹음, 푸시투토크, 파형 표시, 영역 가림, 키 입력·시각 덧표시, 화이트보드다. 확대 효과, 마우스 주변 따라가기, 활동 없음 자동 일시정지, 녹화 취소 단축키, 압축, 다국어 인식 옵션, 날짜별 하위 폴더다. 제외한 것은 일곱이다. 스크롤 캡처, 되감기 버퍼, 게임 후킹 녹화, 워터마크, 클라우드 업로드·공유 링크, 전사문으로 영상 편집, 웹캠 배경 제거다. 요약·할 일 추천은 자매 소프트웨어 연계로 돌렸다.

판정 사유 가운데 셋을 적어 둔다. 소리 다듬기는 전사 정확도가 입력 소리 품질에 달리기 때문이다. 긴 기록 보호는 기록이 파손되면 뒤의 모든 기능이 쓸모없기 때문이다. 화자 분리를 뒤 순위에 둔 것은 공개 모델이 접근 토큰과 약관 동의를 요구해 배포 절차가 따로 필요하기 때문이다.

6. 열둘 안

아홉에 셋을 더한 열둘 안이다. 본편의 3열 카드가 4행이 된다.

번호 핵심기능 하는 일 상태
1 화면 녹화 모니터·영역·창(따라가기)을 MP4 로 기록 있음
2 음성 녹음 마이크와 시스템 소리를 MP3·M4A·WAV 로 기록 있음
3 버전표시(marker) 단축키로 시각과 메모를 찍어 즉시 txt·csv 로 남기고 MP4 챕터로 넣음 있음, 챕터는 다음 판
4 파일 이름 규칙 연도.월.일., 시.분., 주석.확장자 있음
5 녹화 중 제어 미니 막대, 전역 단축키, 초 읽기, 자동 정지, 자기 창 제외, 취소 있음
6 예약 녹화 정한 시각에 시작·정지, 절전 해제 다음 판
7 회의 전사 녹음 파일 또는 외부 파일을 PC 안에서 글로 바꾸고 버전표시 시각을 끼움 다음 판
8 그리기와 강조 녹화 중 펜 판서, 화이트보드, 클릭 강조 다음 판
9 자르기와 내보내기 버전표시 구간 자르기, MP3 추출, GIF, 재인코딩 없음 다음 판
10 소리 다듬기 잡음 억제, 음량 고르기, 무음 구간 표시·제거, 입력 감시 미터 새 후보
11 긴 기록 보호 시간·용량별 자동 분할, 비정상 종료 복구, 디스크 여유 감시, 트랙 분리 저장 새 후보
12 전사문 활용 자막 파일 내보내기, 전사문 검색과 시각 이동, 사용자 사전, 화자 분리 새 후보

7. 사용자가 더한 후보

조사 결과를 검토한 사용자가 여덟 가지를 더 요청하였다. 코드와 기술 검토에는 반영하지 않고 후보로만 올린다. 쉰둘부터 쉰아홉까지다.

번호 후보 쓰임 기본기 시험 PC 안 판정 비고
52 다국어 UI △ △ O O 핵심 후보(요청) 전사 언어와 별개. 번역 파일로 구현
53 다중 OS 호환(Mac·Linux·Android) △ △ △ O 핵심 후보(요청) 화면·소리 캡처 백엔드가 OS 마다 다름. 다른 OS 시험 환경 없음
54 HDR 녹화 △ △ △ O 핵심 후보(요청) 10비트 캡처와 HEVC·AV1 10비트 인코딩. HDR 모니터 없음
55 캡처 묶음(HDR 캡처, GIF 캡처, 녹화 중 캡처) △ O O O 핵심 후보(요청) 스크린샷을 주요기능에서 핵심으로. 기존 캡처 프로그램의 기능 목록 조사 필요
56 코덱 선택, ProRes △ △ O O 핵심 후보(요청) ffmpeg 의 ProRes 인코더로 MOV 기록 가능. CPU 인코딩이라 4K 실시간은 부담
57 16K 녹화, 60·120·240fps X X X O 후보(조건부) 캡처는 모니터 해상도·주사율을 넘지 못함. 16K 는 AV1 만 가능. 장치 없이 시험 불가
58 녹화 중 필기 O △ O O 핵심 유지 8번과 같음
59 불시 종료 복구 O △ O O 핵심 유지 21번과 같음

52번부터 57번까지는 「쓰임」 기준의 정의를 「회의·강의 기록」에서 「범용 녹화·캡처」로 넓혀야 O 가 된다. 정의를 넓히면 핵심기능 수는 열다섯 안팎이 된다.

8. 이름

다음 판(v1.0.1.0)부터 프로그램 이름을 CatchCatch 로 한다. 게시판 이름은 이미 바뀌었다. 기존 판(v1.0.0.0~v1.0.0.2)의 폴더, 개발일지, 게시글은 GenealogyRecording 을 유지한다. 반영 대상은 다음 판부터의 개발 폴더 이름, 창 제목, 실행 파일명, 개발일지 머리글, 게시글 제목과 주소다.

9. 남은 결정

  1. 핵심기능의 수. 아홉을 유지할지, 열둘 안을 받을지, 쓰임의 정의를 넓혀 열다섯 안팎으로 갈지.
  2. 넷째 기준(PC 안에서 끝남)을 기준으로 올릴지.
  3. 요약을 자매 소프트웨어 연계로 둘지.
  4. 판 배정에서 긴 기록 보호를 자르기 앞에 둘지.
  5. 화자 분리를 공개 모델로 할지, 트랙 분리 기반 두 화자로 한정할지.
  6. 전사 엔진의 선택.
  7. 캡처 묶음을 핵심으로 올릴 경우 기존 캡처 프로그램의 기능 조사.

결정되기 전까지 본편 2편의 핵심기능 절과 주요기능 절은 비워 둔다. 결정되면 본편을 다시 쓰고 v1.0.1.0 폴더를 CatchCatch 이름으로 만들어 예약 녹화부터 시작한다.

6편. 이름 변경 및 원천 보완 · v1.0.1.0

2026.10.01. 게시

목적

이름을 CatchCatch 로 바꾼 첫 판을 만든다. 기존 녹화기 비교표의 「원천과 기록」 항목에서 이 프로그램에 없던 네 가지를 넣는다.

계획

  1. 폴더·패키지·설정·실행 파일의 이름을 바꾼다
  2. 마우스 주변 따라가기를 넣는다
  3. 전체화면 앱 캡처를 Desktop Duplication 으로 넣는다
  4. 웹캠 겹치기를 넣는다
  5. 장치 없는 시험과 실행 파일 실기를 돈다
  6. 설치 파일로 배포 형태를 바꾼다
  7. 핵심기능을 확정해 본편에 적는다

체크리스트 9/10

항목 상태 비고
이름 변경(패키지 catchcatch, 설정 폴더 CatchCatch, 옛 설정 복사) 완료
마우스 주변 따라가기 완료
모든 모니터 동시(목록 맨 위) 완료
전체화면 앱 캡처(ddagrab 파이프) 완료
웹캠 겹치기(dshow 파이프, 구석 네 곳) 완료
엔진 시험 8묶음 통과(리눅스·Windows Python) 완료
실행 파일 빌드와 실기(마우스 주변 27초) 완료
설치 파일(NSIS) 빌드 완료
핵심기능 아홉·주요기능 여섯 확정과 본편 반영 완료
전체화면 앱·웹캠·설치 파일 실기 미완 Windows 실기기 필요

1. 판의 목적 및 범위

5편의 조사에서 기존 화면 녹화기 열한 가지와 이 프로그램을 「원천과 기록」 여덟 항목으로 비교하였다. 이 프로그램이 갖추지 못한 항목은 마우스 주변 따라가기, 다중 모니터 동시 녹화, 웹캠 겹치기, 게임 화면 캡처의 넷이었다. 이 판은 그 넷을 채우고, 5편에서 정한 대로 프로그램 이름을 CatchCatch 로 바꾼다. 4편에서 v1.0.1.0 에 배정하였던 예약 녹화와 MP4 챕터는 v1.0.2.0 으로 한 칸 미룬다.

이름 변경과 원천 보완만 넣고 다른 기능은 손대지 않았다. 코드 변경은 screen.py 에 원천 네 가지, pip.py 신설, videowriter.py 와 session.py 에 겹치기 경로, mainwindow.py 에 원천 두 행과 웹캠 그룹, settings.py 에 항목 일곱과 옛 설정 복사다.

2. 이름 변경

표 1은 이름이 바뀐 자리를 나타낸다. 패키지 이름이 바뀌므로 모든 import 문이 바뀌었고, 설정 폴더가 바뀌므로 첫 실행 때 옛 폴더의 settings.json 을 복사해 온다. 복사는 새 설정 파일이 없을 때 한 번만 한다. 이전 판의 폴더와 개발일지와 게시글은 옛 이름을 유지한다.

항목 v1.0.0.2 v1.0.1.0
판 폴더 GenealogyRecording_v1.0.0.2 CatchCatch_v1.0.1.0
Python 패키지 genealogyrecording catchcatch
설정 폴더 %APPDATA%/GenealogyRecording %APPDATA%/CatchCatch (옛 설정 자동 복사)
실행 파일 GenealogyRecording_v1.0.0.2.exe CatchCatch_v1.0.1.0.exe
창 제목·트레이 GenealogyRecording v1.0.0.2 CatchCatch v1.0.1.0
기본 저장 폴더 Videos/GenealogyRecording Videos/CatchCatch
게시글 주소 genealogyrecording-devlog-NN catchcatch-devlog-NN

3. 원천 보완

녹화 모드 화면
그림 1. v1.0.1.0 녹화 모드. 원천에 「마우스 주변」과 「전체화면 앱」 행이, 그 아래에 「웹캠 겹치기」 그룹이 생겼다.

3.1 마우스 주변 따라가기

커서를 가운데 둔 고정 크기 사각형이 커서를 따라간다. 크기는 640×360, 854×480, 1280×720, 1920×1080 가운데 고른다. 구현은 3판의 창 따라가기(FollowSource)를 그대로 쓰고, 창 사각형 대신 커서 위치에서 사각형을 만드는 함수(mouse_provider)를 끼웠다. 사각형이 가상 데스크톱 밖으로 나가면 FollowSource 가 안으로 민다. 커서 위치를 얻지 못한 프레임은 직전 자리를 유지한다.

3.2 모든 모니터 동시 녹화

mss 의 monitors[0] 은 모든 모니터를 합친 사각형이며 3판에도 이미 있었다. 다만 목록에 「모든 모니터」가 보이는 조건이 분명하지 않아 비교표에서 미확인으로 두었다. 이 판은 모니터가 둘 이상이면 목록 맨 위에 「모든 모니터 (가로 × 세로)」를 둔다. 모니터별로 따로 파일을 만드는 방식은 넣지 않았다.

3.3 전체화면 앱 캡처

mss 는 GDI BitBlt 로 찍으므로 배타 전체화면 DirectX 화면을 찍지 못한다. 이 판은 ffmpeg 의 ddagrab 필터(Desktop Duplication API)로 모니터를 통째로 받는 원천(DesktopDupSource)을 더하였다. ffmpeg 가 ddagrab → hwdownload → bgra 로 바꾼 원시 프레임을 표준 출력으로 내보낸다. 읽기 스레드가 가장 새 프레임을 보관하고 VideoWriter 가 가져간다. 창 단위 캡처는 없고 출력 번호(모니터)만 고른다. 동봉한 ffmpeg 7.1 에 ddagrab 과 dshow 가 들어 있음을 확인하였다. ddagrab 이 없는 ffmpeg 이면 항목이 꺼지고 그 이유가 표시된다.

이 방식은 게임 캡처 전용 프로그램의 DirectX 후킹과 다르다. 후킹은 게임 프로세스 안에서 프레임을 가로채므로 게임의 프레임 속도를 그대로 얻지만, Desktop Duplication 은 합성된 화면을 모니터 주사율 안에서 받는다. 회의·강의 기록이 목적인 이 프로그램에는 후자로 충분하다고 판단된다.

3.4 웹캠 겹치기

웹캠 그림을 녹화 화면의 구석에 덮는다(PiP). 카메라는 ffmpeg 의 dshow 로 열고, 3.3 과 같은 파이프 경로로 작은 BGRA 프레임을 받는다. 자리는 오른쪽 아래, 오른쪽 위, 왼쪽 아래, 왼쪽 위의 넷이고, 크기는 출력 가로의 15·20·25·33% 가운데 고른다. 겹치기는 VideoWriter 가 프레임마다 numpy 로 복사해 넣고 2px 흰 테두리를 두른다. 카메라 목록은 ffmpeg 의 장치 목록 출력에서 읽는다. 카메라를 못 열면 겹치기 없이 녹화를 계속하고 그 이유를 표시한다.

3.5 파이프 원천의 공통 구조

3.3 과 3.4 는 PipeSource 하나를 바탕으로 한다. ffmpeg 자식 프로세스의 표준 출력을 읽기 스레드가 프레임 단위(가로×세로×4 바이트)로 받아 가장 새 프레임만 보관한다. 첫 프레임이 10초 안에 오지 않으면 ffmpeg 의 오류 문장을 그대로 들어 실패한다. 장치 없는 환경에서는 같은 클래스에 lavfi testsrc2 를 넣은 PatternSource 로 경로를 시험한다.

4. 시험 결과

표 2는 시험 항목과 결과를 나타낸다. 엔진 시험은 7판까지의 7묶음에 8묶음(v1.0.1.0)을 더해 리눅스 Python 과 wine 위의 Windows Python 에서 모두 통과하였다. 실행 파일은 wine 위의 PyInstaller 로 빌드하였고, Xvfb 화면에서 「마우스 주변」 원천으로 27.3초를 녹화하였다.

항목 방법 결과
마우스 주변 커서 위치 넷을 차례로 넣음 (400,300) → 사각형 (80,120). 화면 밖 두 경우 안으로 밀림. 위치 없음은 직전 유지
파이프 원천 testsrc2 160×120, 10fps 첫 프레임 수신, BGRA 알파 255, 무늬 표준편차 10 이상, 닫은 뒤 프로세스 없음
웹캠 겹치기 320×240 위에 80×60 을 오른쪽 아래 자리 (224,164). 안쪽 값 200, 테두리 255, 바깥 0
겹치기 녹화 가짜 화면 + testsrc2 웹캠 2초 결과 ok, 겹친 프레임 29(리눅스)·24(Windows Python)
ddagrab 명령 명령 문자열 검사 output_idx·framerate·hwdownload·scale 포함
실행 파일 실기 wine, Xvfb, xdotool 로 커서 여섯 자리 이동 1280×720, 819 프레임, 27.3초. 프레임마다 커서가 가운데(그림 2)
전체화면 앱 (wine) DesktopDupSource 열기 「Failed to create D3D11VA device」로 10초 안에 실패. 문장이 사용자에게 전달됨
마우스 주변 녹화의 정지 화면
그림 2. 실행 파일로 녹화한 마우스 주변 영상의 5초 간격 정지 화면. 커서가 각 프레임의 가운데에 있다. wine 은 캡처 제외를 지원하지 않아 미니 막대가 함께 찍혔다.
wine 위에서 실행된 CatchCatch_v1.0.1.0.exe
그림 3. wine 위에서 실행한 CatchCatch_v1.0.1.0.exe. 동봉한 ffmpeg 에 ddagrab 이 있어 「전체화면 앱」 항목이 켜져 있다.

빌드에서 한 가지를 겪었다. wine 에는 Windows 의 시스템 ICU(icuuc.dll)가 없어 PyInstaller 가 Qt 플러그인을 모으지 못하였다. 빌드와 실기 때만 빈 함수로 된 대역 DLL 을 PySide6 폴더에 두고, 배포본에서는 뺐다. Windows 10 이상에는 시스템 ICU 가 있다.

5. 배포 형태 변경

v1.0.0.2 까지는 실행 파일 폴더를 zip 두 조각으로 나누어 올렸고, 받은 사람이 같은 폴더에 풀어 실행 파일을 열어야 했다. 이 판부터 NSIS 3 으로 만든 설치 파일 하나(CatchCatch_v1.0.1.0_Setup.exe, 50.4 MB)로 배포한다. 설치 파일은 폴더의 파일 87개(198 MB)를 LZMA 로 압축해 담는다. 실행하면 Program Files/CatchCatch 에 풀고 시작 메뉴·바탕 화면 바로 가기와 「프로그램 추가/제거」 항목을 만든다. 제거는 설정과 녹화 결과를 남긴다. 이전 판이 설치돼 있으면 먼저 지운다. 설치 스크립트는 installer/CatchCatch.nsi, 빌드는 build_installer.bat 이다.

설치 파일은 32비트 실행 파일이라 64비트 전용 wine 에서는 돌지 않아 실기를 하지 못하였다. 7z 로 담긴 파일 87개와 실행 파일·ffmpeg·Qt 라이브러리가 들어 있음을 확인하였다. 설치와 제거의 실기는 Windows 실기기에서 한다.

6. 핵심기능 확정

4편의 아홉 안과 5편의 열둘 안을 두고 미루어 온 결정을 이 판에서 내렸다. 결정의 요지는 「쓰임」의 정의를 회의·강의 기록에서 범용 녹화·캡쳐로 넓힌 것이다. 그에 따라 5편에서 조건부로 두었던 고해상도·고주사율과 요청 후보였던 캡쳐 묶음·스트리머 기능이 핵심에 들어왔다. 회의 전사는 「음성 녹음 및 자막」 안으로, 긴 기록 보호는 「녹화 파일 분할」 안으로 들어갔다. 버전표시와 파일 이름 규칙은 모든 모드의 바탕이므로 따로 세지 않는다. 표 3은 확정한 핵심기능 아홉과 v1.0.1.0 의 상태를 나타낸다.

번호 핵심기능 담는 것 v1.0.1.0 상태
1 고해상도 (8K) 모니터 해상도 그대로, HEVC·AV1 4K 까지 확인
2 고주사율 (240Hz) 60·120·240fps, 하드웨어 인코더 60fps 까지 확인
3 스크린샷 (캡쳐) 전체·영역·창·모니터, 녹화 중 캡쳐, 스크롤·HDR 캡쳐 있음(스크롤·HDR 제외)
4 녹화 파일 분할 시간·용량 분할, 비정상 종료 복구, 손상 파일 복구 없음
5 녹화 중 필기·메모 클릭 강조(좌·중·우), 화면 필기, 화이트보드 왼쪽 클릭 강조만
6 녹화 자동화 예약 녹화, 자동 정지, 절전 해제 시간 기준 자동 정지만
7 녹화본 기본 편집 자르기·합치기·MP3 추출·GIF, 재인코딩 없음 없음
8 음성 녹음 및 자막 녹음 전용 모드, 최대 32비트, MP3·M4A·WAV·FLAC, PC 안 전사와 SRT 녹음 있음(16비트), 자막 없음
9 스트리머 모드 웹캠 겹치기, 배경 제거, 크로마키, 영역 가리기, 워터마크, 로고 웹캠 겹치기만

주요기능은 여섯이다. HDR 지원(녹화·캡쳐), 화면 구역 선택, 다국 언어 지원, 다양한 플랫폼 지원, 노이즈 필터 지원, 다양한 포맷 지원이다. 화면 구역 선택은 모니터 하나·다중 모니터·N개 모니터·웹캠 겹치기·마우스 따라가기·게임 후킹을 묶은 것이다. 플랫폼은 Windows·Mac·Linux·Android, 포맷은 코덱과 확장자를 뜻한다. 5편에서 핵심 후보로 두었던 다국 언어·다중 OS·HDR·코덱 선택은 주요기능으로 자리를 잡았고, 제외했던 게임 후킹·워터마크·웹캠 배경 제거는 다시 들어왔다. 본편의 핵심기능 절과 주요기능 절을 이 표대로 적었다.

이 판에 이미 있는 것은 아홉 가운데 셋(스크린샷, 녹음, 웹캠 겹치기)뿐이고 나머지는 부분 또는 없음이다. 다음 판부터의 배정은 7편에서 다시 정한다.

7. 한계 및 남은 일

전체화면 앱 캡처와 웹캠 겹치기는 wine 과 리눅스에서 장치가 없어 실기를 하지 못하였다. 파이프 경로와 실패 처리까지만 확인하였고, Windows 실기기에서 ddagrab 이 실제 화면을 주는지와 dshow 가 카메라를 여는지는 다음 확인 항목이다. 파이프로 원시 프레임을 받는 방식은 1080p 30fps 에서 초당 약 250MB 를 옮기므로, 느린 PC 에서는 출력 크기를 줄이는 쪽이 안전하다.

다음 판 v1.0.2.0 은 핵심기능 4(녹화 파일 분할)와 6(녹화 자동화) 가운데 먼저 할 것을 7편에서 정한다. 4편의 판 배정은 6절의 확정으로 다시 짠다.

7편. 화면 재구성과 필기·스크린샷·고주사율 · v1.0.2.0

2026.10.03. 게시

목적

6편에서 확정한 핵심기능 아홉 가운데 1(고해상도), 2(고주사율), 3(스크린샷), 5(필기)를 넣는다. 그에 앞서 주 창을 목업으로 다시 짜고 그 목업대로 만든다.

계획

  1. 주 창 목업을 만들어 겉모습을 먼저 정한다
  2. 필기 구현 방식을 기존 프로그램 조사로 정한다
  3. 필기 덧창과 유리 도구 막대를 넣는다
  4. 스크린샷을 셋째 탭과 녹화 중 단추로 넣는다
  5. 120·144·240fps 와 8K 출력, 코덱 고르기를 넣는다
  6. 설정 창을 아홉 묶음으로 나눈다
  7. 시험과 빌드, 설치 파일을 만든다

체크리스트 14/15

항목 상태 비고
목업 34판(1440×900, 좁은 세로 화면, 터치) 완료
필기 사전조사(기존 프로그램 다섯과 필기 앱 하나) 완료
필기 덧창(펜 넷·지우개 셋·강조선·도형 아홉·올가미·글·레이저) 완료
도구별 두께·색상·투명도·필압 하위 메뉴 완료
필기와 막대가 녹화에 안 찍힘(WDA_EXCLUDEFROMCAPTURE, 프레임 합성) 완료
스크린샷 탭(PNG·JPG·WebP, 지연, 커서·필기·클립보드) 완료
녹화 중 스크린샷 단추와 단축키 완료
120·144·240fps(Desktop Duplication 경로) 완료
출력 크기 1080p~8K, H.264 한계 넘으면 HEVC 완료
코덱 H.264·HEVC·AV1, 인코더 자동·CPU·NVENC·QSV·AMF 완료
예약 시작·무음 정지·절전 해제 완료
엔진 시험 9묶음 81항목(리눅스·Windows Python) 완료
실기 41항목(Xvfb) 완료
실행 파일·설치 파일 빌드와 wine 실기 완료
하드웨어 인코더·240fps·펜 필압·캡처 제외의 Windows 실기기 확인 미완

1. 판의 목적 및 범위

6편은 핵심기능 아홉을 확정하고 다음 판의 배정을 7편으로 미루었다. 이 판은 그 가운데 넷을 고른다. 고해상도(1), 고주사율(2), 스크린샷(3), 녹화 중 필기(5)다. 6편에서 v1.0.2.0 에 두었던 파일 분할(4)과 녹화 자동화(6)는 자동화의 일부(예약 시작, 무음 정지, 절전 해제)만 넣고 분할은 다음 판으로 보낸다. 넷을 고른 까닭은 모두 녹화 화면과 주 창의 모양을 바꾸는 일이라, 창을 한 번에 다시 짜는 편이 두 번 고치는 것보다 적게 들기 때문이다.

이 판은 기능보다 화면을 먼저 정하였다. HTML 목업을 34판까지 고치며 겉모습을 확정한 뒤 그대로 코드로 옮겼다. 코드 변경의 중심은 mainwindow.py 전면 재작성과 파일 일곱의 신설이다. 신설 파일은 widgets, settingsdialog, recordscreen, shotpage, ink, inkoverlay, shot 이다. 그 밖에 ffmpegtool.py 에 코덱 표와 인코더 고르기를, videowriter.py 에 출력 크기와 필기 합성을 더하였다. session.py 에 캡처 방식과 소리 경로를, settings.py 에 항목 마흔여섯을 더하였다. 패키지는 6,699줄이며 신설 파일이 4,017줄을 차지한다.

2. 주 창 재구성

v1.0.2.0 주 창의 화면 녹화 탭
그림 1. 화면 녹화 탭. 위에 탭 셋과 설정 단추, 왼쪽에 대상 카드 다섯과 세부 줄·미리보기·품질 줄, 오른쪽에 소리와 웹캠, 아래에 저장 경로와 시작 단추.

이전 판의 주 창은 라디오 단추와 콤보 상자를 세로로 쌓은 설정 화면이었다. 이 판은 「무엇을 찍을지」를 카드 다섯으로 세우고, 카드를 고르면 그 대상의 세부 줄만 아래에 바뀌어 나오게 하였다. 카드는 모니터, 영역, 창, 마우스 주변, 게임이다. 6편의 「전체화면 앱」은 「게임」으로 이름을 바꾸고 「일반 캡처로 검게 나올 때」를 부제로 달았다. 창 카드의 세부 줄은 열린 창의 실제 목록을 보여 주고, 고른 창이 최소화돼 있으면 미리보기에 영역 대신 「창 숨김」을 띄운다. 모니터 세부 줄에서 모니터를 바꾸면 미리보기도 그 모니터로 바뀐다.

미리보기는 1초마다 mss 로 다시 찍고, 영역 대상에서는 미리보기 위에서 사각형을 끌어 고른다. 품질 줄은 셋이다. 품질(낮음·보통·높음·최고), 프레임(15·24·30·60·120·144·240fps), 출력 크기(원본·1080p·1440p·4K·8K·75%·50%)다. 오른쪽 열은 마이크와 시스템 소리의 켜기 스위치·장치·수준계, 웹캠의 켜기·구석·크기다. 아래 막대는 저장 경로, 변경, 열기, 여유 공간, 주석 입력, 녹화 시작 단추, 단축키 안내다.

음성 녹음 탭
그림 2. 음성 녹음 탭. 형식·비트·소리 쓰임을 고르고, 녹화와 같은 아래 막대를 쓴다.

음성 녹음 탭은 형식(MP3·M4A·WAV·FLAC)과 비트 깊이에 더해 「소리 쓰임」 줄을 얻었다. 영상에 섞을지, 따로 둘지, 둘 다 할지와 따로 둘 때의 형식을 고른다. 녹화 탭에서도 이 설정을 따르므로 영상 곁에 마이크만 담은 MP3 를 함께 남길 수 있다.

설정 창의 영상 묶음
그림 3. 설정 창. 왼쪽 목록에서 묶음을 고른다. 영상 묶음에 코덱·인코더·캡처 방식이 있다.

설정은 주 창에서 빼어 창 하나에 아홉 묶음(영상, 소리, 웹캠, 표식, 필기, 단축키, 저장, 자동, 화면)으로 모았다. 영상 묶음의 코덱·인코더·캡처 방식, 자동 묶음의 예약 시작 시각·무음 정지 분·절전 해제, 화면 묶음의 트레이 시작이 이 판에서 생긴 항목이다.

3. 녹화 중 화면

녹화 중 화면과 필기
그림 4. 녹화 중 화면. 지금 찍히는 프레임이 창을 거의 채우고, 왼쪽 아래 둥근 유리 단추 셋(표식, 필기, 스크린샷)은 녹화에 찍히지 않는다. 수치와 표식 줄은 아래 두 줄이다.

녹화를 시작하면 주 창이 둘째 쪽으로 바뀐다. 영상 자리는 VideoWriter 가 마지막으로 보낸 프레임을 0.2초마다 줄여 보여 주므로 커서·웹캠·필기가 실제 찍히는 그대로 보인다. 아래 첫 줄은 파일 크기, 실제 프레임, 놓친 프레임, 여유 공간, 마이크·시스템 수준계, 일시정지, 정지다. 둘째 줄은 표식 메모 입력, 표식 찍기, 필기, 표식 목록이다. 작은 막대로 가면 이 화면 대신 구석의 막대만 남고, 막대에도 필기와 스크린샷 단추가 있다.

주 창·덧창·막대는 모두 SetWindowDisplayAffinity 의 WDA_EXCLUDEFROMCAPTURE 로 캡처에서 제외한다. 이것이 「녹화에 안 찍힘」의 근거이며 Windows 10 2004 이상에서 동작하므로 요구 운영체제를 그 판으로 두었다.

일시정지 상태
그림 5. 일시정지. 시계가 흐려지고 단추가 「재개」로 바뀐다.
녹화를 마친 뒤의 주 창
그림 6. 정지 뒤 첫 쪽으로 돌아온 주 창. 아래 막대에 결과 파일과 열기 단추가 보인다.

4. 필기

4.1 구현 방식의 선택

코드에 앞서 기존 프로그램 다섯(녹화기 둘, 발표용 그리기 도구 둘, 방송용 녹화기 하나)과 태블릿 필기 앱 하나의 방식을 조사하였다. 녹화기와 그리기 도구는 투명한 최상위 창(덧창)에 그리고 그 창을 화면과 함께 찍는 방식이 대부분이다. 이 방식은 덧창의 도구 막대까지 찍히므로 막대를 화면 밖으로 치우거나 캡처 제외로 숨겨야 한다. 방송용 녹화기는 그리기를 소스로 두어 합성한다.

이 판은 두 길 가운데 「프레임 합성」을 골랐다. 덧창은 입력을 받고 사용자에게 보여 주는 일만 하고, 획 자료(InkState)를 VideoWriter 가 프레임마다 numpy 로 합성한다. 덧창 자체는 캡처에서 제외한다. 이렇게 하면 도구 막대와 선택 테두리가 영상에 들어가지 않고, 획의 투명도와 사라짐이 영상과 화면에서 같게 나온다. 획은 바뀔 때만 다시 그리고, 바뀌지 않은 프레임에서는 직전 그림을 합성하므로 1080p 30fps 에서 추가 부담이 작다. 사라지는 중인 획이 있을 때만 프레임마다 다시 그린다.

4.2 도구

필기 도구 막대
그림 7. 필기 도구 막대. 흰 유리 모양이며 화면 가운데 위에 뜬다. 왼쪽부터 펜, 지우개, 강조선, 도형, 올가미, 글, 레이저, 되돌리기·다시, 지우기, 아래 창 조작, 닫기.

표 1은 도구 일곱과 각 도구의 하위 메뉴를 나타낸다. 두께·색상·투명도는 전역 항목이 아니라 도구마다 따로 두었고, 도구 단추를 다시 누르면 하위 메뉴가 열린다. 두께는 pt 와 화면 높이 % 의 두 단위를 고를 수 있고 직접 입력도 된다. 색은 열여섯 가지, 투명도는 10% 단위다.

도구 갈래 하위 메뉴
펜 볼펜, 만년필, 붓, 형광펜 두께, 색상, 투명도, 필압(만년필·붓)
지우개 지나간 자리만, 지나간 자리 넓게, 획 통째로 두께, 형광펜만
강조선 형광, 실선, 점선, 일점쇄선, 이점쇄선 × 가로, 세로, 자유 각도 두께, 색상, 투명도
도형 손으로 그림(인식), 직선, 화살표, 상자, 타원, 삼각형, 마름모, 오각형, 육각형, 별 두께, 색상, 채움
올가미 둘러 고르기 옮기기, 복제, 지우기
글 누른 자리에 입력 크기, 색상
레이저 지나간 자리가 곧 사라짐 없음
펜의 하위 메뉴
그림 8. 펜의 하위 메뉴. 갈래, 두께(pt·%), 색상, 투명도, 필압.

「지나간 자리만」 지우개는 획을 지나간 자리에서 쪼갠다. 획의 점 사이를 지우개 반지름 절반 간격으로 보간(densify)한 뒤 지우개가 지나간 선분과의 거리로 가른다. 지우개 포인터도 이동 사이를 보간하므로 빠르게 지나가도 빠지지 않는다. 지우개를 고른 뒤 획을 지워도 펜으로 돌아가지 않는다. 도형의 「손으로 그림」은 끝난 획의 꼭짓점 수와 닫힘으로 직선·화살표·상자·타원·삼각형을 인식한다. 나머지 도형은 종류를 고르고 끌어서 크기만 정한다.

「아래 창 조작」은 덧창을 입력에 투명하게(WindowTransparentForInput) 바꾸어 필기를 둔 채 아래 창을 쓰는 상태다. 이전 목업의 「통과모드」를 뜻이 보이게 고친 이름이다. 단축키는 필기 켜기 Ctrl+Alt+D, 아래 창 조작 Ctrl+Alt+G, 모두 지우기 Ctrl+Alt+0 이다. 덧창 안에서는 P·E·H·S·L·T·Q 로 도구를 바꾸고 Ctrl+Z·Y 로 되돌린다. 마우스, 태블릿 펜(필압), 손가락 터치의 세 입력을 받는다.

설정 창의 필기 묶음
그림 9. 설정의 필기 묶음. 사라짐 초, 펜 입력만 받기, 필기 JSON 곁 저장, 막대 자리.

획은 결과 파일 곁에 「필기.json」으로도 남길 수 있다. 시각·도구·점·색을 담으므로 다음 판의 편집 기능에서 다시 쓸 수 있다.

5. 스크린샷

스크린샷 탭
그림 10. 스크린샷 탭. 대상 카드 넷, 형식·지연·함께 담을 것, 저장 폴더, 찍기 단추, 미리보기, 최근 찍은 것.

스크린샷은 녹화 탭의 곁 기능에서 셋째 탭으로 올라섰다. 대상은 모니터, 모든 모니터, 영역, 창의 넷이며 형식은 PNG·JPG(90)·WebP, 지연은 바로·3·5·10초다. 커서와 필기를 함께 담을지와 클립보드에도 복사할지를 고른다. 저장 폴더는 기본이 Pictures/CatchCatch 이고 이름 규칙은 녹화와 같다. 녹화 중에는 녹화 중 화면과 작은 막대의 단추, 단축키(Ctrl+Alt+S)로 찍으며 그때의 대상은 녹화 영역이다. 녹화 중이 아닐 때는 탭에서 고른 대상이다. 6편 본편에 「없음」으로 적었던 지연·클립보드·JPG 저장이 이 판에서 들어왔고 스크롤·연속·HDR 캡쳐는 남았다.

영역 대상의 미리보기
그림 11. 영역 대상. 미리보기 위에서 사각형을 끌어 고르고 모서리를 끌어 크기를 바꾼다. 녹화와 스크린샷이 같은 부품을 쓴다.

6. 고주사율·고해상도

프레임 선택에 120·144·240 을 더하였다. mss 의 GDI 캡처는 60fps 를 넘기기 어렵다. 60 을 넘는 값이나 캡처 방식을 「Desktop Duplication」으로 둔 경우에는 6편의 DesktopDupSource 를 쓴다. 이 판에서 그 원천에 crop 필터를 더해 모니터 통째가 아닌 영역·창 사각형도 받을 수 있게 하였다. 영역이 어느 모니터에 있는지는 monitor_of 로 찾는다. ddagrab 이 없는 ffmpeg 이면 60 으로 내리고 그 이유를 표시한다.

출력 크기는 원본 외에 1080p·1440p·4K·8K 와 75·50% 를 두었다. 코덱은 H.264·HEVC·AV1 이며 인코더는 자동·CPU·NVENC·QSV·AMF 가운데 고른다. 자동은 코덱별로 하드웨어 인코더를 한 번 탐지해 두고 없으면 CPU 인코더(libx264, libx265, libsvtav1)를 쓴다. 출력이 4096×2304 를 넘으면 H.264 규격 밖이므로 HEVC 로 바꾸고 안내한다. 하드웨어 인코더 탐지는 창이 뜬 2.5초 뒤 스레드에서 돌린다.

표 2는 이 판의 상한을 나타낸다. 어느 것도 Windows 실기기에서 확인한 값이 아니며, 경로와 명령과 결과 파일의 코덱·크기만 장치 없는 환경에서 확인하였다.

항목 v1.0.1.0 v1.0.2.0 확인한 범위
프레임 15·24·30·60 15·24·30·60·120·144·240 240 계획이 ddagrab 없는 환경에서 60 으로 내려감. 실제 240 수신은 미확인
출력 크기 원본·75%·50% 원본·1080p·1440p·4K·8K·75%·50% 50% 결과 파일 크기 확인. 8K 는 명령만
코덱 H.264 H.264·HEVC·AV1 HEVC 결과 파일 확인(libx265). AV1 은 인코더 인수만
인코더 자동(NVENC·QSV·AMF) 자동·CPU·NVENC·QSV·AMF 선택 CPU 만. 하드웨어 셋은 명령 인수만
캡처 방식 GDI, 전체화면 앱만 Desktop Duplication 자동·GDI·Desktop Duplication 선택, crop 지원 crop 필터 문자열

7. 자동화와 소리

예약 시작은 설정에 HH:MM 을 적으면 그 시각에 녹화 시작과 같은 경로를 탄다. 무음 정지는 마이크와 시스템 소리의 수준이 정한 분 동안 문턱 아래이면 멈춘다. 절전 해제는 녹화 중 SetThreadExecutionState 로 화면 끄기와 절전을 막는다. 소리는 영상에 섞기, 따로 두기, 둘 다의 셋이며 따로 둘 때 MP3·M4A·FLAC 으로 변환한다. 표식은 txt·csv 외에 하나만 남기는 선택이 생겼고 찍을 때 소리를 낼 수 있다.

설정 창의 소리 묶음
그림 12. 설정의 소리 묶음. 소리 쓰임과 따로 둘 때의 형식.

8. 시험 결과

표 3은 시험 항목과 결과를 나타낸다. 엔진 시험은 8묶음에 9묶음(v1.0.2.0)을 더해 81항목이 되었고 리눅스 Python 과 wine 위의 Windows Python 에서 모두 통과하였다. 실기 시험은 새 화면에 맞추어 다시 썼으며 Xvfb 위에서 41항목을 통과하였다.

항목 방법 결과
필기 합성 320×180 프레임에 획 하나를 합성 획 자리 색 바뀜, 밖은 그대로. 판 번호가 같으면 다시 그리지 않음
지우개 직선 획 가운데를 「지나간 자리만」으로 지남 획이 둘로 쪼개지고 양끝은 남음
도형 인식 손으로 그린 상자·직선 점 열 rect·line 으로 인식
되돌리기·JSON 획 셋, 되돌리기 하나, 다시 하나 획 셋. JSON 에 도구·점·색 저장
출력 크기 3840×2160 을 1080p·50%·8K 로 1920×1080, 1920×1080, 7680×4320. 짝수 맞춤
코덱 고르기 h264 에 8K 출력 HEVC 로 바뀌고 안내문 생김. CPU 인코더 libx265
인코더 인수 nvenc·qsv·amf·libx265·libsvtav1 품질 인수가 각 인코더 형식으로 나옴
스크린샷 저장 PNG·JPG·WebP 로 저장 세 파일 생성, 이름 규칙 일치
소리 경로 따로 두기 + 영상 섞기, 백업 MP3 영상에 트랙 하나, 곁에 MP3 둘
실기: 필기 덧창 Xvfb 에서 Ctrl+Alt+D 뒤 마우스 끌기 획 생성, 지우개로 쪼개짐, 상자 인식, 강조선, 올가미 고르기
실기: 녹화 중 스크린샷 녹화 중 Ctrl+Alt+S 녹화 영역 크기의 PNG 저장, 최근 목록에 추가
실기: HEVC 50% 2초 녹화 결과 코덱 hevc, 크기 절반
실기: 240fps 계획 ddagrab 없는 ffmpeg 60 으로 내려가고 안내문 표시
실행 파일(wine) Ctrl+Alt+R·M·D·S 차례로 녹화·표식·필기 덧창과 유리 막대·스크린샷 저장·결과 mp4
설치 파일(wine) WoW64 접두사에서 /S 설치 Program Files/CatchCatch 190 MB, 제거 파일 생성

실행 파일은 wine 위의 PyInstaller 로 빌드하였다. 6편과 같이 ICU 대역 DLL 을 빌드와 실기 때만 두고 배포본에서 뺐다. 설치 파일은 6편에서 실기를 못 하였으나 이 판은 32비트 wine 접두사를 따로 만들어 조용한 설치까지 확인하였다. 설치 파일은 83개 파일(189 MB)을 담아 50.6 MB 다.

wine 에서 겪은 것이 셋이다. 첫째, 하드웨어 인코더 탐지 스레드를 창을 만드는 중에 돌리면 wine 이 죽어 창이 뜬 뒤로 미루었다. 둘째, 글꼴 밖 글자(이모지)를 단추에 쓰면 간헐적으로 죽어 기본 다국어 평면 안의 기호로 바꾸었다. 셋째, 한글 곁 파일 이름(표식.txt, 필기.json)을 만들지 못하는 환경이 있어 영문 이름으로 물러서게 하였다. 셋 다 Windows 실기기에서는 나지 않을 것으로 보이나 고친 쪽이 안전하다.

9. 한계 및 남은 일

wine 과 Xvfb 에는 합성기와 캡처 제외가 없어 덧창이 검게 보이고 주 창이 영상에 찍힌다. 따라서 「녹화에 안 찍힘」과 투명 덧창의 겉모습, 하드웨어 인코더, 실제 240fps 수신, 태블릿 펜의 필압은 모두 Windows 실기기 확인 항목으로 남는다. 터치 입력은 목업에서 휴대 전화로 확인하였고 코드는 Qt 의 터치 이벤트를 받으나 실기기 확인은 하지 못하였다.

6편 본편의 핵심기능 아홉 가운데 이 판으로 셋(스크린샷, 필기, 고해상도·고주사율은 「경로 있음, 실기 전」)이 바뀌었다. 다음 판 v1.0.3.0 은 파일 분할(4)과 녹화본 기본 편집(7)을 둔다. 필기 JSON 을 편집 기능에서 다시 그리는 일이 여기에 들어간다.

ABOUT AUTHOR

shind

shind

소개글이 아직 없습니다.

댓글 남기기

Your email address will not be published. Required fields are marked *