녹음·전사 자동화 앱 Recly 만들기

 

녹음과 전사를 자동화하는 앱, Recly 개발기.

워치·폰·PC에서 녹음하면 내 Drive에 업로드하고 전사한 뒤, 평소 쓰는 AI로 활용하는 Recly의 사용 흐름

GitHub에서 코드 보기

Plaud를 찾아보다가

친구가 Plaud로 모든 회의와 중요한 대화를 녹음한다고 했다. 나도 찾아봤지만 가격이 부담스러웠다. 어떤 기능을 쓰는지 물어보니, 주로 전사와 요약을 하고 결과를 평소 쓰는 AI에 넣어 활용한다고 했다.

회사에서 AX 업무를 하면서도 비슷한 생각을 자주 했다. 서비스마다 AI 기능이 붙지만, 평소 쓰는 Claude Code나 Codex 등 범용 에이전트에서 할 수 있는 일도 많았다. 그쪽에는 이미 자료와 대화 내용, 지침이 있어 작업을 이어가기 편하다. 결국 서비스에서 만든 결과를 복사해 옮기게 된다.

그렇다면 내게 필요한 기능은 무엇일까. 세 가지로 좁혀보았다.

  • 대화 중에도 쉽게 누를 수 있는 녹음 버튼
  • 녹음이 끝나면 내 저장소에 파일을 올려주는 기능
  • 음성을 텍스트로 바꾸는 전사

이후의 작업은 평소 쓰는 AI에서 하면 된다. 워치와 폰에는 이미 마이크가 있으니, 녹음한 파일을 내 저장소에 올리고 전사하는 기능을 붙여보기로 했다. 그렇게 만든 앱이 Recly다.

필요한 기능 정하기

Recly는 워치·폰·데스크톱에서 녹음한 파일을 사용자의 Google Drive에 올린다. 전사를 설정하면 선택한 제공자의 API를 사용자 키로 호출하고, 결과를 원본과 같은 폴더에 저장한다.

Galaxy Watch의 Recly 녹음 대기 화면
Galaxy Watch
Android 앱의 워크플로우 선택과 녹음 버튼
Android
macOS 메뉴 막대 앱의 녹음 버튼과 처리 완료 목록
macOS

워치의 녹음은 폰으로 넘긴다. 업로드와 전사는 폰·데스크톱에서 처리한다.

앱에서는 전사까지만 처리하고, 회의록 작성과 분석은 평소 쓰는 AI에서 이어간다. 그쪽에 있는 기존 자료와 지침도 함께 활용할 수 있다.

예시 스킬로 노트 만들기

간단한 예시 스킬도 만들어 두었다. 사용하는 AI에 Drive와 Notion을 연결하고 스킬을 추가하면, 전사 내용을 읽어 회의록을 쓰고 Notion에 저장한다. 요청하면 원문도 함께 넣어준다.

최근 녹음으로 회의록을 만들어서 Notion에 저장해줘. 전사 원문도 같이 넣어줘.

저장한 기록을 찾아 분석할 수도 있다.

지난주 회의에서 가격에 대해 어떤 이야기가 나왔는지 정리해줘.

Notion은 예시일 뿐이다. 스킬을 고쳐 Markdown 파일로 저장하거나 다른 도구에 연결해도 된다. 원본과 전사 결과가 파일로 남으니, 양식과 분석할 내용도 원하는 대로 바꿔 쓰면 된다.

웹훅으로 녹음 메타데이터와 Drive 링크를 보내 후속 작업을 자동화할 수도 있다. 전사와 웹훅은 선택 사항이라, 녹음과 원본 보관만으로도 사용할 수 있다.

대신 초기 설정은 번거롭다. 앱과 AI에 Drive를 연결하고 전사 API 키도 입력해야 한다. API와 저장소 비용도 별개다. 한 번 설정하면 녹음할 때마다 파일을 옮길 필요는 없다.

Recly의 구조

Recly 아키텍처. 각 기기의 공통 코어가 사용자 Drive와 전사 API를 연결하고, 외부 AI가 결과를 활용한다.

플랫폼별 구현과 공통 코어

클라이언트는 여섯 종류다. 워치는 녹음과 파일 전달을 맡고, 폰·데스크톱은 워크플로우를 실행한다.

구분 플랫폼별로 구현한 부분 녹음 이후의 처리
Galaxy Watch · Android Kotlin · Compose, 녹음, Data Layer 전송 워치는 폰에 전달, 폰이 실행
Apple Watch · iPhone · macOS SwiftUI, 오디오 캡처, WatchConnectivity 등 워치는 iPhone에 전달, iPhone과 Mac이 실행
Windows Compose Desktop, Rust의 WASAPI 캡처 헬퍼, ffmpeg PC에서 실행

운영체제에 따라 달라지는 녹음, 백그라운드 실행, 기기 간 전송은 플랫폼 코드가 담당한다. 워크플로우, 작업 큐, 업로드, 전사, 웹훅은 Kotlin Multiplatform 코어에서 처리하므로, 폰과 데스크톱이 원본 보관과 재시도 규칙을 공유한다.

공통 코어는 각 앱에 포함되는 라이브러리다. 플랫폼이 파일시스템, 보안 저장소, 인증과 실행 스케줄을 담당하고, 코어는 녹음 등록과 작업 처리를 담당한다. Apple 앱에서는 XCFramework로 빌드해 Swift에서 참조한다.

Google Drive에 파일 저장하기

Recly에는 자체 백엔드가 없다. 폰과 데스크톱이 Google Drive와 전사 API를 직접 호출한다.

Drive에는 녹음별 폴더에 오디오와 메타데이터를 저장한다. 전사 결과는 제공자와 관계없이 같은 형식의 JSON과 텍스트로 남긴다. 텍스트는 직접 읽거나 AI에 전달하고, JSON은 다른 프로그램에서 처리할 수 있다.

recly/2026/2026-09/
└── {base}/                         녹음 하나
    ├── {base}_p001_mono.m4a        오디오 파트 1
    ├── {base}_p002_mono.m4a        오디오 파트 2
    ├── {base}.meta.json           녹음 메타데이터
    ├── {base}.transcript.json     구조화한 전사 결과
    └── {base}.transcript.txt      읽기용 전사 결과

모바일 녹음의 저장 예시. {base}는 녹음별 파일명 접두사다. 전사 파일은 해당 단계를 실행했을 때 추가된다.

Drive 연결에는 앱이 만들거나 사용자가 앱과 공유한 파일에 접근하는 drive.file 권한을 사용한다. Google Drive 권한 문서

워크플로우와 API 키는 기기에만 저장한다. 워크플로우는 파일로 내보내 옮길 수 있지만, 키 값은 제외한다. 새 기기에 해당 키가 없으면 실행 오류를 표시하므로 따로 입력해야 한다. 기기 간 자동 동기화는 지원하지 않는다.

API 호출이 실패하거나 앱이 중단되면, 기기에 저장한 진행 상태를 읽어 다음 실행에서 재개한다.

구현 세부 사항

녹음은 나누어 저장하고, 전사는 합쳐서 처리하기

녹음은 약 15분 단위의 파일로 저장한다. 앞서 본 p001, p002가 각각 하나의 파트다. Android에서는 녹음 중 앱이 종료돼 작성 중인 .m4a 파일이 정상적으로 닫히지 않으면, 그 파일을 읽지 못할 수 있다. 파일을 나누어 완성해두면 마지막 파트에 문제가 생겨도 앞서 완성된 파트는 앱을 다시 실행했을 때 복구할 수 있다. 녹음 복구 코드

전사할 때는 같은 트랙의 파트들을 재인코딩 없이 이어 붙여 하나의 파일로 보낸다. 전체 녹음을 기준으로 화자를 구분하므로, 파트마다 따로 전사할 때 생기는 화자 라벨 불일치를 피할 수 있다. 다만 모델이 화자를 잘못 구분하는 문제는 별개로 생길 수 있다. 전사 API에 보내기 전에는 합친 파일이 크기와 길이 한도를 넘는지도 확인한다. 오디오 처리 규칙 · 한도 검사

이어 붙인 파일에서 나온 전사 결과는 파트별 시작 시간을 이용해 원래 녹음의 시간 기준으로 보정한다. 녹음 중 공백이 있었더라도 전사 결과의 시간과 원본을 맞춰볼 수 있다. 시간 보정 코드

데스크톱 회의 녹음의 세 가지 트랙

데스크톱의 회의 녹음은 마이크 소리를 담은 mic, 컴퓨터에서 재생되는 소리를 담은 sys, 둘을 합친 mix를 별도로 저장한다. 온라인 회의에서 내 목소리와 컴퓨터로 듣는 상대방의 목소리가 함께 녹음되는 방식이다. 세 트랙은 같은 시작 시각과 파일 분할 경계를 공유한다. 트랙 구성

전사에는 두 소리가 합쳐진 mix를 사용한다. 모바일·워치 녹음이나 데스크톱의 마이크 전용 녹음은 mono 트랙 하나를 사용하고, 이때는 그 파일이 전사 입력이 된다. 녹음 모드별 트랙 · 전사 입력 규칙

전사 API마다 다른 호출 방식 처리하기

전사 API는 응답에 결과를 바로 담아주기도 하고, 작업 ID를 반환한 뒤 나중에 조회하도록 하기도 한다. 코어는 이 차이를 SttProvider 인터페이스로 처리한다. 결과가 바로 오면 저장하고, 작업 ID가 오면 기기에 남겨두었다가 이후 실행에서 진행 상태를 조회한다. 별도의 콜백 수신 서버 없이 동작하는 구조다. 전사 실행 코드

인증과 요청·응답 형식의 차이는 제공자별 어댑터가 처리한다. 결과의 화자 라벨은 등장 순서대로 S1, S2처럼 통일하고, 공통 형식의 JSON과 텍스트로 저장한다. 결과를 읽는 쪽에서는 전사 제공자마다 다른 형식을 다루지 않아도 된다. 제공자 인터페이스 · 결과 정규화

언제 원본을 지워도 되는가

폰에 파일이 도착해도 검증이나 작업 등록에 실패하면 다시 보내야 한다. 워치는 폰의 최종 확인을 받을 때까지 원본을 보관한다.

워치는 파트 ACK를 받아도 파일을 보관한다. 폰이 녹음과 작업 큐 등록을 처리하고 최종 ACK를 보낸 뒤에만 원본을 삭제한다.

파트 ACK를 받아도 보관하고, 최종 ACK를 받으면 삭제한다.

폰에서 녹음 등록이나 작업 큐 처리 중 예외가 나면 최종 ACK인 ack-meta ok:true를 보내지 않는다. 워치에는 원본이 남아 재전송할 수 있다. 최종 ACK 구현

폰이 처리를 마쳤는데 ACK만 유실될 수도 있다. 재전송된 파일이 중복 등록되지 않도록 하고, 작업은 (recordingId, workflowId)로 식별해 이미 완료했다면 다시 만들지 않는다.

그사이 폰이 로컬 파일을 정리했다면 워치가 파일까지 다시 보내야 할 수도 있다. 재전송 비용은 들지만, 최종 확인을 받기 전까지 워치의 원본은 남아 있다.

폰과 데스크톱은 다음 조건으로 원본을 정리한다.

녹음의 처리 상태 로컬 원본
모든 작업 완료 + 하나 이상의 Drive 업로드 단계가 전체 성공 7일의 보관 조건을 충족한 파트부터 정리
업로드 실패 후 다음 단계로 넘어감 계속 보관
웹훅만 실행하고 업로드하지 않음 계속 보관
서버 없이 실패한 작업을 이어가기

Drive 업로드는 기기에 진행 상태를 남겨두고, 다음 실행에서 세션을 확인해 이어 보낸다. 이미 올라간 파일은 이름과 MD5로 확인해 건너뛰고, 세션이 만료됐으면 새로 시작한다.

두 번째 오디오 파트의 업로드가 503으로 중단되면 세션과 오프셋을 저장한다. 재실행 시 첫 파트는 건너뛰고 두 번째 파트를 이어서 올린다.

앱 업데이트로 읽을 수 없게 된 작업은 해당 작업에만 오류를 표시하고, 나머지는 계속 실행한다. 나중에 다시 처리할 수 있도록 원본 JSON도 보존한다.

테스트에서는 업로드 중 503 응답이나 알 수 없는 작업 단계 등을 재현해 업로드 재개작업 격리 동작을 검증한다.

남은 일

Recly는 아직 프리릴리스 단계다. 플랫폼마다 배포와 실기기 검증 수준도 다르다.

기기마다 API 키와 워크플로우를 설정해야 하는 점도 번거롭다. 착용감, 음질, 배터리 사용 시간은 전용 녹음기와 비교해봐야 한다.

실제로 얼마나 수고가 줄었는지 보려면 초기 설정 시간, 녹음 후 전사까지 걸리는 시간, 직접 재시도해야 하는 빈도도 측정할 필요가 있다.

여러 기기에서 사용해보며, 녹음이 끝난 뒤 직접 손봐야 하는 상황을 줄여보려 한다.

소스 코드설치 안내는 GitHub에 공개해 두었다.