Refactoring English: 9개월 차
원문은 Michael Lynch님이 에 게재했습니다. 이 블로그 구독하기
한 줄 요약
영상 인터뷰 편집의 기쁨과 고통
하이라이트
- 초기 독자들에게 챕터 목록에 대한 유용한 피드백을 받았다.
- 인터뷰 영상 편집은 답답했지만, 트랜스크립트를 만드는 과정은 즐거웠다.
- 프리랜서 블로그 편집 서비스를 홍보하려던 계획이 기대 이상으로 잘 풀렸다.
목표 평가
매달 초에 달성하고 싶은 목표를 정한다. 이번 달 목표를 얼마나 달성했는지는 다음과 같다:
이전에 대화한 적 없는 독자 20명에게 개인화된 이메일 보내기
- 결과: 대신 챕터 설문조사를 하기로 함
- 평점: 해당 없음
몇몇 독자와 대화하면서, 현시점에서는 모든 독자를 대상으로 한 폭넓은 설문조사를 하는 것이 더 나은 전략이라는 걸 깨달았다.
Refactoring English 새 챕터 출간하기
- 결과: “Get to the Point” 출간
- 평점: A
드디어 서론에 관한 챕터를 마무리했다. 서론은 내가 글쓰기에서 가장 어려워하는 부분이라 이번 챕터가 가장 쓰기 힘들었다. 그래서 이번 챕터는 서론에 대한 글이면서, 동시에 내가 서론을 어떻게 쓰는지를 역으로 분석해 보려는 시도이기도 했다.
이번 챕터에는 예산도 훨씬 초과했다. 처음에는 6시간만으로 예산을 잡았었다가 결국 19시간을 들였다.
남은 마케팅 과제 완료하기
- 결과: 인터뷰 편집은 마쳤지만 콜 투 액션은 완성하지 못함
- 평점: B+
가장 큰 미완 과제였던 인터뷰 편집은 끝냈다. 다만 책 웹사이트 디자인을 무료 메일링 리스트 구독이 아닌 얼리 액세스 구매에 초점을 맞추도록 조정하는 작업은 아직 손을 대지 못했다.
Refactoring English 지표
| 지표 | 2025년 7월 | 2025년 8월 | 변화 |
|---|---|---|---|
| 고유 방문자 수 | 8,061 | 2,863 | -5,198 (-64%) |
| 사전 주문 수익 | $800.04 | $312.63 | -$487.41 (-61%) |
| 스폰서 수익 | $48.25 | $48.25 | $0.00 (0%) |
| 총 수익 | $848.29 | $360.88 | -$487.41 (-57%) |
지난달에는 책 관련 지표가 건전하다고 생각했다. 인기 있는 새 글을 올리지 않았는데도 웹사이트 방문자 수와 수익이 모두 증가했기 때문이다.
그 뒤로 지표 그래프를 추가하고 나니 다른 패턴이 보였다. 책 수익이 책 웹사이트 방문자 수와 밀접하게 연관되어 있는 것으로 보인다. 7월에는 인기 글이 없었는데도 괜찮다고 생각했지만, 8월에 책 웹사이트에 아무 것도 올리지 않자 지표가 급락했다.
내가 얻은 교훈은 결국 웹사이트에 계속 새로운 콘텐츠를 올려야 새로운 독자, 특히 책에 돈을 지불할 의향이 있는 독자를 계속 찾을 수 있다는 것이다.
챕터 목록에 대한 독자 피드백 해석하기
독자들과 개별적으로 대화해 보니, 어떤 챕터가 유용하다고 느끼는지에 대한 의견이 매우 다양했다. 독자들이 가장 관심 있어 하는 챕터가 무엇인지 알아보는 더 나은 방법은 설문조사를 돌리는 것이겠다고 생각했다.
예전에 메일링 리스트를 통해 피드백을 요청했을 때 응답이 몇 건에 그쳤기 때문에 이번에도 응답률이 낮을 거라 예상했다. 그런데 의외로 독자들이 이번 설문조사에 훨씬 적극적으로 참여해 2주 만에 133개의 응답이 모였다.

응답에 대한 자세한 분석은 책 웹사이트에 올려 두었다:
요약하자면 유용한 피드백을 받았고, 그 덕분에 챕터 순서를 바꾸고 독자들이 별로 좋아하지 않은 챕터를 다시 구성하게 됐다.
이전 피드백 요청과 비교했을 때 응답률 차이가 나는 것도 흥미로웠다. 예전에는 샘플 챕터를 보낸 뒤 피드백을 요청했는데, 그때와 이번의 차이는 독자에게 요구하는 작업량에 있다고 생각한다. 이번 설문조사는 몇 분이면 끝낼 수 있지만, 챕터에 대한 피드백을 주려면 챕터를 읽고 고민하는 데 30분은 써야 한다. 설문조사를 받는 시점에 그럴 준비가 되어 있지 않을 수도 있다.
30분짜리 영상 인터뷰 편집이 의외로 어려웠던 이유
2024년 7월, 블로깅 강좌인 Hit the Front Page of Hacker News를 리부트하는 과정에서 Adam Gordon Bell과 인터뷰를 녹화했다. 육아휴직에 들어가기 전까지 강좌를 끝내지 못했고, 결국 리부트 계획은 무기한 보류됐다.
그 바람에 이 인터뷰가 어정쩡하게 남게 됐다. Adam이 기꺼이 시간을 내주었는데 인터뷰를 전혀 공개하지 않자니 죄책감이 들었다.
Refactoring English 얼리 액세스를 제공하기 시작했을 때, 인터뷰를 공개하기에 좋은 타이밍이라고 생각했다. 사람들이 인터뷰를 좋아하면 책에도 관심을 가질지 모르니까.
계속 미루다가 ‘이걸 이렇게 오래 미루다니 바보 같다. 그냥 앉아서 한 시간만 하면 끝날 텐데, 머릿속에서 계속 짊어지고 있을 필요가 없잖아’라고 생각하게 되는 그런 일이 있지 않은가. 나는 이 인터뷰도 분명 그런 일일 거라고 확신했다.
하지만 그렇지 않았다.
오디오 싱크 어긋남이라는 고질병의 귀환
인터뷰는 Riverside라는 서비스를 이용해 녹화했다. 통화가 끝나면 Riverside는 통화 양쪽의 영상 파일을 각각 생성하고, 대화가 합쳐지고 동기화된 버전도 만들어 준다. 당시에는 영상이 제대로 작동하는지 대충 확인만 하고 자세히 보지는 않았다.
합쳐진 버전을 그대로 YouTube에 올리기만 하면 될 줄 알았다. 혹시 끊김이나 긴 곁가지 이야기가 있으면 잘라내면 되겠지만, 영상은 거의 완성된 상태라고 생각했다.
녹화한 지 1년 만에 영상을 제대로 앉아서 보게 됐을 때, 오디오와 비디오가 싱크가 맞지 않는다는 걸 깨달았다. 영상에서 입이 움직이기 전에 목소리가 먼저 들렸다.
Riverside가 생성한 영상에서는 오디오와 비디오가 약간 어긋나 있었다.
괜찮다, 별일 아니다. FFmpeg로 비디오를 다시 처리해서 오디오를 살짝 밀면 되니까.
그런데 아니었다. 대화 양쪽의 오디오 어긋남 정도가 서로 달랐던 것이다. Adam 쪽은 약 425ms, 내 쪽은 약 150ms가 밀려 있었다. 그래서 대화 양쪽의 원본, 즉 합쳐지지 않은 영상으로 돌아가 각각의 싱크를 바로잡은 뒤 직접 다시 합쳐야 했다.
쓸 만한 오픈소스 영상 편집기 찾기
예전에는 영상 편집할 때 주로 Adobe Premiere를 썼지만, 작년에 Linux로 갈아탄 뒤로는 Premiere를 쓸 수 없게 됐다. 게다가 이제는 회사로서의 Adobe에도 신물이 난 상태다.
그래서 지난여름부터 배우고 있던 영상 편집기인 Shotcut으로 편집을 시작했다. Shotcut에서 영상을 나란히 배치하는 방법조차 알아내는 데 시간이 걸렸지만, 결국 확대/축소 및 자르기 필터를 조합해 어찌어찌 해냈다.
Shotcut에서 편집할 때는 재생이 엄청나게 끊겼다. 꽤 새 고사양 데스크톱에서도 1080p 영상 두 개를 합치는 데 버벅였기 때문이다. 그래서 영상이 실제로 어떻게 들리는지 확인하려면 영상을 내보내야 했다. 그런데 Shotcut은 영상의 일부만 내보내는 기능을 지원하지 않아서, 매번 30분짜리 전체를 내보내야 했고 그때마다 몇 시간이 걸렸다. 참고로, 나중에 Shotcut에서 재생 해상도를 낮추면 편집 중 성능이 빨라진다는 걸 알게 됐다.
내보낸 뒤에야 클립을 분할할 때마다 Shotcut이 큰 ‘팝’ 소리를 끼워 넣는다는 걸 알게 됐다. 분할 지점에서 실제로 아무 것도 자르지 않아도 생겼다. 하나의 연속된 클립을 인접한 두 클립으로 나누는 행위만으로 팝 노이즈가 생긴 것이다.

아무 변경 없이 클립을 분할하기만 해도 오디오에 ‘팝’ 노이즈가 생겼다.
그 팝 소리가 Shotcut의 알려진 이슈라는 걸 알게 됐을 때는 믿기지 않았다. 분할할 때마다 거슬리는 오디오 아티팩트가 생기는데 어떻게 영상을 편집하라는 말인가? 하지만 많은 댓글에서 모든 영상·오디오 편집 도구에 같은 문제가 있다고 하더라.
뭐라고?!
나는 다른 도구로 수백 개의 미디어 파일을 편집해 봤지만, 클립을 분할할 때 팝 소리를 끼워 넣는 경우는 한 번도 본 적이 없다.
Linux용 다른 오픈소스 영상 편집 도구들도 시도해 봤다. Kdenlive는 편집을 시작한 지 몇 분 만에 충돌했고, Flowblade는 아예 로드되지 않았지만 결국 해결 방법을 찾았다. 그리고 Flowblade는 Shotcut을 더 단순하게 만든 느낌이라, 다시 Flowblade에서 편집을 시작하면서 나란히 배치된 영상을 만드는 방법을 또 알아내야 했다.
Flowblade에서 한 시간 정도 편집한 뒤 영상을 내보내 보니 팝 소리가 다시 나타났다. 거기에도 관련 버그가 있었고, 그들이 파악한 원인은 Dan Dennedy의 설명에 기반한 것이었다. 그는 바로 Shotcut의 개발자다. 그리고 Flowblade는 Shotcut을 구동하는 것과 같은 미디어 프레임워크인 MLT 위에 구축된 것으로 보였다. 결국 똑같은 버그로 돌아온 셈이다.
어쨌든 이 편집 모험담은 이미 너무 길고 지루하니 결론만 말하자면, 결국 영상의 오디오 샘플링 레이트를 44.1 kHz에서 48 kHz로 변환해서 팝 소리를 우회했다. 그러자 팝 아티팩트가 사라졌지만, 왜 그런지는 모르겠다.
영상을 편집하면서 다른 버그들도 많이 겪었지만, 여기서 일일이 설명하기엔 너무 지루하다.
영상 편집에서 얻은 교훈
- 가능한 한 많은 전처리를 FFmpeg 스크립트로 하라.
- 나중에 전처리를 조정해야 할 경우를 대비해 FFmpeg 스크립트를 저장해 두라.
- 다시는 전처리를 할 일이 없을 거라고 확신하더라도 스크립트를 저장하라, 가급적 소스 컨트롤에 넣어라.
- FFmpeg 스크립트가 의도대로 동작하는지 확인하기 위해 극단적인 값으로 테스트하라.
- 오디오 싱크를 바로잡기 위해 오디오를 200ms 이동시켜 봤지만 여전히 어긋나 있었다. 그래서 300ms로 시도했고, 여전히 어긋났다. 그다음엔 400ms. 결국 2000ms로 건너뛰어 보고 나서야 200ms 보정과 2000ms 보정이 똑같이 들린다는 걸 깨닫고 스크립트에 버그가 있음에 틀림없다고 생각했다.
- 올바른 설정을 확신할 수 없을 때는 FFmpeg로 여러 버전을 만들도록 스크립트를 짜서 옵션을 비교하라.
- 나는 내 쪽 대화의 배경 소음을 제거하기 위한 다양한 전략을 테스트할 때 이렇게 했다.
- 44.1 kHz 오디오 샘플링 레이트는 편집할 때 문제를 일으키는 것 같다.
- 전처리 과정에서 레이트를 48 kHz로 변환하니 팝 아티팩트가 해결됐다.
- 왜 그런지는 전혀 모르겠다.
- 편집 초기에 영상을 내보내 최종 결과물을 확인해 보라.
- 영상/오디오 편집 필터는 클립 레벨이 아니라 트랙 레벨에 적용하라.
- 처음에는 하나의 거대한 클립뿐이라도, 편집을 시작하고 나면 독립적인 필터 설정을 가진 수십 개의 클립이 생긴다.
- 필터를 잘못 적용했다는 걸 깨달으면 모든 클립에서 다시 작업해야 한다.
인터뷰 트랜스크립트 작업에 너무 신나 버린 이야기
Adam Gordon Bell과의 영상 편집을 마쳤으면 그걸로 끝이어야 하지 않나? 영상 편집에 그렇게 많은 시간을 썼으니 당연히 빨리 공개하고 마무리하고 싶었을 것이다.
천만에!
영상 편집을 마치자 이번에는 트랜스크립트에 집착할 차례였다. 그런데 이 작업은 실제로 재미있었다.
온라인에서 보는 인터뷰 트랜스크립트들은 디자이너가 “60년 전 타자기로 친 법정 속기록을 가져와서 그 수준의 재미와 상호작용을 그대로 웹에 옮겨 보자”라고 한 것 같은 느낌이 든다.

웹 브라우저를 이용해 대화 트랜스크립트를 더 흥미롭게 만들면 어떨까?
제발! 타자기에서는 불가능한 것들을 웹에서는 해 보자.
그래서 whisper-ctranslate2로 초기 트랜스크립트를 생성한 뒤, 정확하고 인터랙티브하며 읽기 재미있게 만드는 데 많은 시간을 들였다:

인터뷰 트랜스크립트를 재미있게 읽기 위해 작은 기능들을 추가했다.
- 대화의 각 당사자가 서로 다른 색깔의 말풍선으로 표시되어 누가 말하는지 한눈에 알 수 있다.
- 각 말풍선에는 작은 재생 버튼 아이콘이 있다. 아이콘을 클릭하면 페이지가 영상으로 스크롤되면서 트랜스크립트의 해당 시점부터 재생된다.
- 내가 좋아하는 인용구를 뽑아 콜아웃으로 넣었다.
- 대화의 구조를 잡아 주는见出し를 추가했다.
- 전사 오류가 있는지 텍스트를 검토했다.
아직 영상을 공개하지는 않았다. 금요일에 메일링 리스트 구독자들에게 새 챕터를 막 발송했기 때문이다. 이번 주 말(2025-09-12)까지는 책 블로그에 올라갈 예정이다.
Tyler Cipriani의 Hacker News 1위 달성 돕기
때로는 계획이 기대했던 것보다 훨씬 더 잘 풀리기도 한다.
실제 작가들에게 피드백을 주는 것이 책을 쓰는 데 도움이 되기 때문에, 다른 인디 개발자 블로거들을 대상으로 프리랜서 편집 일을 해 왔다. 편집 서비스를 설명하는 페이지에 내 편집 작업 샘플을 넣고 싶었지만, 이미 비용을 지불한 유료 클라이언트에게 그 작업물을 내 마케팅에 활용하게 해 달라고 부탁하고 싶지는 않았다.
그래서 내 계획은 내 편집 노트를 공개하고 나를 에디터로 크레딧해 주는 조건으로 글을 무료로 편집하게 해 줄 사람을 찾는 것이었다.
도전 목표는 그 글이 Hacker News나 Lobsters, reddit처럼 내 책의 잠재 독자들이 모이는 곳에서 관심을 끄는 것이었다. 독자가 글 끝까지 읽고 “Edited by Refactoring English”라는 문구를 보면 “오, 이게 뭐지?”라고 생각하게 만들고 싶었다.
또 과거 클라이언트를 가리키며 “봐라, 이 사람이 나를 고용했고 그의 글이 당신이 성공하고 싶은 곳에서 성공했다”라고 말할 수 있다면 잠재 클라이언트에게도 좋은 인상이 될 것이다.
몇 달 전 Tyler Cipriani가 내게 블로그에 대한 전반적인 리뷰를 의뢰했다. 그가 결과에 만족하는 것 같아 무료 편집 아이디어를 제안했고, 그는 동의했다.
Tyler와 함께 그의 글 “The future of large files in Git is Git.”에 대해 몇 차례 피드백을 주고받았다. 함께 작업하는 과정이 즐거웠고, 책에 대한 좋은 아이디어도 얻을 수 있었다.
내 추가 목표는 그저 Hacker News 프론트 페이지에 오르는 것이었는데, 그걸 넘어 Hacker News에서 1위까지, Lobsters, 그리고 reddit 모두에서 1위를 차지했다.
우리 둘 모두에게 가장 큰 교훈 중 하나는 글을 타깃 독자에 맞게 조정하는 것의 중요성이었다. Tyler 글의 초기 초안은 독자가 대용량 파일을 관리하는 Git 확장 기능인 Git LFS를 잘 알고 있다고 가정하고 있었다.
나는 일반적인 Git 사용자라면 글의 모든 내용을 이해할 만큼 Git LFS를 잘 알지 못할 수도 있다고 제안했다. Tyler는 대용량 파일을 다뤄 본 일반적인 Git 사용자라면 당연히 Git LFS를 알 것이라고 생각해 처음에는 반박했다.
독자가 그의 글이 가정한 것보다 Git LFS에 대해 덜 알고 있다는 걸 Tyler에게 납득시키기 위해, 나는 내 Git LFS 지식과 경험을 나열해 봤다:
- git 저장소에 큰 파일이 있거나 바이너리 데이터를 자주 업데이트한다면 git LFS를 써야 한다
- 나는 git LFS를 한 번도 써 본 적이 없다
- Git LFS를 사용하는 오픈소스 프로젝트를 1~2개 정도 작업해 본 적은 있지만, LFS 부분은 전혀 건드린 적이 없다.
- 각종 포지의 용량 제한이 얼마인지 모르지만, 그 제한에 걸리면 포지에서 경고를 줄 것이고 그때 가서 처리하면 된다고 생각했다
- git 저장소에 5MB가 넘는 파일을 저장하고 싶을 때는 일단 피할 방법을 찾기 시작한다
- Git LFS는 어디서나 쓸 수 있는 포지 독립적인 기능인 줄 알았다.
- Git LFS는 10년 넘게 된 기술이고 성숙하고 안정적이라고 생각했다
- 한 번 Git LFS를 사용하기 시작하면 저장소가 거기에 묶인다는 것도 몰랐다
- git에서 대용량 파일을 저장하는 방법에는 관심이 있고 HN이나 Lobsters에서 그런 글을 보면 클릭하겠지만, git 저장소에 정말 큰 파일을 저장하고 싶어지는 상황에 처하지 않는 한 미리 고민해서 해결하려 들 문제는 아니다.
Tyler는 이 목록이 자신에게는 “아하” 하는 순간이었다고 말했다. 이전에는 독자들이 Git LFS를 알고 있을 거라고 확신했기 때문에 피드백을 받아들이지 않았는데, 내 목록을 보고 독자들이 Git LFS가 무엇이고 무엇을 위한 것인지 피상적으로는 알고 있을지 몰라도 어떻게 동작하는지는 모를 수도 있다는 걸 깨달았다고 한다.
Tyler의 깨달음에서 멋진 점은 그가 내 목록을 스스로도 쓸 수 있었다는 것이다. 그는 타깃 독자가 무엇을 알지에 대해 나와 같은 예측을 하고 있었다. 다만 독자가 어떤 기술을 “안다”는 것이 무엇을 의미하는지에 대해 한 단계 더 깊이 생각할 필요가 있었던 것이다.
사이드 프로젝트
Hacker News Observer를 시계열 데이터베이스로 전환해 500배 빨라지다
지난 몇 년간 “시계열 데이터베이스”에 대해 이야기하는 사람들을 들어 왔지만, 그것이 무엇을 하는 것이고 일반 관계형 데이터베이스와 어떻게 다른지 이해하지 못했다. 작년에 Grafana와 호환되는 무언가가 필요해서 사이드 프로젝트에 InfluxDB를 쓰기까지 했지만, 여전히 무엇이 그것을 “시계열” 데이터베이스로 만드는지, 왜 그냥 SQLite를 쓰면 안 되는지 이해하지 못했다.
최근에 다른 개발자와 이야기하다가 그가 시계열 데이터베이스를 사용해 초 단위 세분성과 일 단위 같은 데이터의 다양한 뷰를 만든다고 언급했다. 그는 그 이상 자세히 설명하지도 않았는데, 내 머릿속에서 전구가 켜지면서 “아! 시계열 데이터베이스가 바로 그걸 위한 거구나!” 하고 생각했다.
Hacker News Observer는 매분 Hacker News를 조회해 최근 몇 주간의 모든 스토리의 추천 수, 댓글 수, 순위를 기록하는 사이드 프로젝트다. 더 깊이 파고들어 흥미로운 패턴을 찾고 싶지만, 지금은 프론트 페이지의 총 추천 수와 댓글 수 같은 고수준 집계만 보고 있다:

DuckDB로 전환하자 이 페이지 속도가 500배 빨라졌다
처음에는 데이터베이스로 SQLite를 사용했는데, 위 그래프를 렌더링하는 데 2분이 걸렸다. 하루에 수천 개의 스토리가 있고, 각 스토리마다 수천 개의 스냅샷이 있으며, 각 스냅샷에서 상위 30개(프론트 페이지)를 찾은 뒤 이를 시간 단위 버킷으로 묶어야 하니 그럴 만도 하다. SQLite에는 분 단위 데이터를 시간 단위 뷰로 집계하는 특별한 함수가 없어서 비용이 많이 드는 쿼리가 많았다.
시계열 데이터베이스에 대한 아이디어를 얻은 뒤, LLM에게 SQLite와 유사한 시계열 데이터베이스 옵션을 물어봤고, DuckDB를 추천받았다. 그리고 LLM에게 데이터베이스를 SQLite에서 DuckDB로 마이그레이션하도록 시켰다. 그 마이그레이션만으로 그래프 로드 시간이 2분에서 250ms로 줄어, 약 500배 빨라졌다.
그러니까 시계열 데이터베이스가 바로 그런 용도인 것 같다.
Gleam Chat Log Parser로 오래된 로그 조금씩 처리하기
채팅 로그 파서 프로젝트는 조금씩만 진전이 있었다. 자리 비움 메시지가 포함된 로그와 Windows 스타일 줄바꿈(\r\n)이 있는 로그를 처리했다. 이상하게도 Erlang(따라서 Gleam에서도)에서는 \r\n이 하나의 문자로 취급되는데, 이 때문에 한동안 헤맸다.
마무리
무엇을 해냈나?
- Refactoring English의 “Get to the Point” 챕터를 출간했다.
- “Give Your Spouse the Gift of a Couple’s Email Domain”을 출간했다.
- AirGradient 공기질 모니터를 커맨드 라인에서 플래싱하는 튜토리얼을 출간했다.
- “Reader Feedback about my Chapter List”를 출간했다.
- 낮 동안 집중력을 지키기 위해 LeechBlockNG를 다시 사용하기 시작했다.
- 이번에는 잘 작동하고 있다! 메모리 누수도 없고, 업무 시간 중에 소셜 미디어로 새는 것을 막아 준다.
배운 점
- 영상 편집을 더 체계적으로 하라
- 인터뷰 영상 편집은 지루하지만, 트랜스크립트를 편집하고 스타일링하는 건 재미있다.
- 30분이 걸리는 작업보다 몇 분이면 끝나는 작업일 때 피드백을 주려는 고객이 열 배 더 많다.
다음 달 목표
- Refactoring English 웹사이트에 새로운 독자를 끌어들이는 콘텐츠를 발행하기.
- Refactoring English 새 챕터 발행하기.
- 이전에 대화한 적 없는 독자 20명에게 개인화된 이메일 보내기.
글을 무작위로 읽기
댓글
로그인하고 댓글 남기기