본문으로

StarLink실시간 통역 iOS 앱 · 1인 개발

말이 끝나야 시작하던 통역을
말하는 도중 귀로 듣는 통역으로

청각장애 당사자로서 겪은 불편에서 시작한 iOS 앱입니다. 주변의 영어·일본어·중국어를 한국어 음성으로 바꿔 에어팟이나 보청기로 바로 들려주고, 화면에는 원문 언어를 붙인 자막을 띄웁니다.

약 20초 뒤 멈추던 통역 → 계속 이어지는 통역Gemini 자동 발화 감지를 끈 뒤 · 실기기 데모 영상 · 지연 시간은 따로 재지 않음

내 담당기획 · iOS 앱과 오디오 연결 · Python 통역 서버와 접속 열쇠 서버 · AI가 쓴 초안 코드의 오류 추적과 수정

내가 정한 것
말 끊김을 찾는 장치를 모두 끄고 소리를 끊지 않고 흘려 넣는 방식 · 자막 언어를 서버 안에서 글자 범위로 판단
AI로 짠 것
iOS 앱과 통역 서버의 초안 코드
내가 확인한 것
통역을 멈춘 오류 1007·-3001·-50을 오류 기록과 라이브러리 동작에 맞대어 원인 추적 · 블루투스 소리는 실기기에서 확인

이주형Swift · SwiftUI · LiveKit · Gemini Live · Python · 데모용 개인 빌드(앱스토어 심사 전)

데모 영상 보기 GitHub 저장소

통역 한 번이 흘러가는 길

아이폰 → 중계 서버 → 통역 서버 → 이어폰

  1. 듣기

    아이폰 마이크가 주변 외국어를 받아 LiveKit(실시간 음성 중계 서비스)으로 끊지 않고 보냅니다.

  2. 통역

    Python 통역 서버가 그 소리를 Gemini Live에 계속 흘려 넣고 한국어 음성으로 돌려받습니다.

  3. 자막

    원문과 번역을 문장 단위로 짝짓고, 글자 모양으로 언어를 가려 [영어]·[일본어] 표시를 붙입니다.

  4. 귀로

    한국어 음성은 연결된 에어팟·갤럭시 버즈·블루투스 이어폰·MFi 보청기로 나가고, 화면에는 자막이 추가됩니다.

통역이 멈추지 않게 바꾼 과정

개발 기록 · 통역 서버 코드

  1. 문제

    처음에는 말이 끊긴 틈을 찾아 그때마다 통역을 요청했습니다. 통역 음성이 마이크로 되돌아와 다시 통역되거나, 첫 문장 뒤 또는 약 20초 뒤에 통역이 멈췄습니다.

  2. 판단

    Gemini Live 통역 모델은 소리를 끊지 않고 계속 받도록 만들어졌다고 보고, 말 끊김을 찾는 장치(휴대폰 쪽 음성 감지, Gemini 자동 발화 감지)를 모두 껐습니다.

  3. 검증

    남은 멈춤은 오류 번호로 하나씩 추적했습니다. 라이브러리가 자동으로 보내던 응답 요청은 가로채 막았고, 마이크를 직접 끄면 이어폰 소리까지 멈춰서 대신 모델에게 한국어 음성은 무시하라고 지시했습니다.

  4. 결과

    통역, 음성 출력, 보청기 연결이 한 흐름으로 이어서 동작합니다. 같은 연결 위에 받아쓰기만 하는 회의록 모드도 추가했습니다.

지금 동작하는 범위

실기기 데모로 확인

3 → 1영어·일본어·중국어를 한국어로
4종기기별 설정 없이 소리를 보내는 무선 기기
2모드: 통역 · 회의록 받아쓰기
13개발 중 남긴 디버깅 기록

통역 지연 시간은 따로 재지 않았습니다. 앱스토어 심사를 거치지 않은 개인 빌드이고, 무료 인증서라 7일마다 다시 서명해야 합니다. 블루투스 소리 연결은 시뮬레이터에서 시험할 수 없어 실기기에서만 확인했습니다.

자막 옆 언어 표시

외부 서비스에 묻지 않고 판단

def detect_language(text):
    if any('가' <= c <= '힣' for c in text):
        return "ko"
    if any('\u3040' <= c <= '\u30ff' for c in text):
        return "ja"
    if any('一' <= c <= '鿿' for c in text):
        return "zh"
    latin = sum(1 for c in text if 'a' <= c.lower() <= 'z')
    return "en" if latin > len(text) * 0.3 else "unknown"
통역 서버의 언어 판단 코드 일부를 줄여 옮김

글자 범위만 보고 원문 언어를 고름

여러 언어가 섞인 대화에서는 지금 들은 말이 무슨 언어였는지 알려 줘야 합니다. 번역 서비스에 언어를 물으면 기다리는 시간이 늘어나서, 통역 서버 안에서 글자 범위로 바로 판단하게 했습니다.

  • 한글이 있으면 한국어, 가나가 있으면 일본어
  • 한자만 있으면 중국어, 알파벳이 30%를 넘으면 영어
  • 결과는 자막과 함께 앱으로 보내 [영어]·[일본어] 표시로 띄움

궁금한 부분을 더 자세히

통역을 멈추게 한 오류 세 가지1007 · -3001 · -50

오류 기록과 라이브러리 동작을 맞대어 원인을 찾고 고쳤습니다.

오류무슨 일이 있었나고친 방법
1007
통역 서버
라이브러리가 자동으로 보내는 응답 요청과, 모드를 바꿀 때 보내던 지시문 변경을 Gemini 통역 모델이 거부하며 연결을 끊음응답 요청 함수를 바꿔 끼워 아무것도 보내지 않게 하고, 모드는 서버 안에서 상태로만 기억
-3001
iOS 앱
블루투스 기기가 연결되자마자 오디오를 켜면 오디오 엔진이 멈춤보청기가 연결돼 있으면 0.8초 기다린 뒤 오디오 시작
-50
iOS 앱
폰 스피커로 직접 돌리면 LiveKit의 자동 소리 설정이 덮어쓰며 실패직접 돌리기를 버리고 LiveKit이 제공하는 스피커 우선 설정으로만 조절
개발하며 막힌 네 지점되돌아오는 소리 · 새는 소리 · 함께 멈추는 자막 · 시작 직후 꺼짐
되돌아오는 소리

"then, and then…"이 끝없이 반복

처음에는 음성 감지로 마이크를 바로 여닫았는데, 통역 소리의 잔향이 다시 들어가 번역이 멈췄습니다. 마이크 끄기와 음성 감지를 모두 버리고, 끊지 않고 흘려 넣게 바꿨습니다.

새는 소리

보청기 대신 폰 수화기로 나감

자동 설정과 직접 설정 모두 통화 모드로 덮어써져 소리가 나지 않았습니다. 소리 설정은 LiveKit 자동 설정에 맡기고 출력 방향만 스피커 우선 설정으로 조절했습니다.

함께 멈추는 자막

같은 흐름을 두 곳이 동시에 읽음

통역 서버와 라이브러리가 같은 메시지 흐름을 동시에 읽으면서 자막과 소리가 같이 멈췄습니다. 흐름을 먼저 감싸서 자막 글자만 복사해 보내게 바꿔 둘 다 살렸습니다.

시작 직후 꺼짐

끼어들기를 막자 세션이 바로 종료

통역 중 끼어들기를 막으려던 설정이 라이브러리 내부 오류를 냈습니다. 모든 발화에 끼어들기를 허용하고 Gemini 자동 발화 감지를 꺼서 안정시켰습니다.

구조iOS 앱 · LiveKit · Python 통역 서버 · 접속 열쇠 서버
iOS 앱

소리 받기와 내보내기

SwiftUI 화면, LiveKit 연결, 보청기 연결 상태를 살피는 관리자로 나눴습니다. 마이크 소리를 올려 보내고, 돌아온 통역 음성은 연결된 무선 기기로 재생합니다.

LiveKit

소리와 자막을 중계

앱과 통역 서버를 같은 방에 넣어 소리를 양쪽으로 주고받습니다. 자막은 같은 연결의 데이터 통로로 따로 보냅니다.

통역 서버

Gemini Live 연결

Python으로 짠 서버가 방의 소리를 받아 Gemini Live에 넘기고, 원문과 번역 글자를 문장 단위로 짝지어 자막으로 보냅니다.

접속 열쇠

1시간짜리 열쇠와 내 키로 쓰기

별도 서버가 1시간 뒤 만료되는 접속 열쇠(토큰)를 내줍니다. 설정 화면에 자기 LiveKit 주소와 열쇠를 넣으면 서버 비용 없이 개인 키로도 쓸 수 있습니다.

앱에 들어 있는 기능무선 기기 · 자막 · 회의록 · 보청기 보호
무선 기기에어팟, 갤럭시 버즈, 일반 블루투스 이어폰, MFi 보청기를 기기별 설정 없이 똑같이 처리
자막통역 음성과 함께 번역 자막을 띄우고, 원문 언어를 [영어]·[일본어]처럼 표시
회의록 모드통역 없이 받아쓰기만 하는 모드. 대화 기록을 텍스트 파일로 내보내 공유
보청기 보호보청기가 연결돼 있으면 폰 스피커로 강제 전환을 막음. 전환하면 출력 방향이 계속 바뀌며 소리가 끊기기 때문. 보청기 호환을 위해 영상통화용 오디오 모드 대신 기본 모드 사용
상태와 기술 정보개발 방식 · 코드 규모 · 남은 한계
상태데모용 개인 빌드. 무료 인증서로 7일마다 다시 서명, 앱스토어 심사 전
개발 기간2026년 6월, 약 3일 집중 개발
만든 방식AI가 쓴 초안 코드를 받아 오류 기록과 라이브러리 동작을 대조하며 직접 수정
코드 규모Swift 2,483줄 · Python 857줄. 자막 짝짓기와 언어 판단을 확인하는 Python 자동 시험 17개
기술Swift 5.9 · SwiftUI · AVFoundation · XcodeGen · LiveKit · LiveKit 에이전트 · Gemini 3.5 Live · Python 3.11+ · aiohttp
남은 한계통역 지연 시간을 재지 않았습니다. 블루투스 소리 연결은 실기기에서만 확인할 수 있습니다. 보청기가 연결된 동안에는 폰 스피커로 돌릴 수 없습니다.
라이선스MIT 공개 소스
이주형 · StarLink

말이 끝나야 들리던
통역을말하는 도중에

청각장애 당사자가 직접 만든 iOS 통역 앱입니다. 주변의 외국어를 한국어 음성으로 바꿔 무선 이어폰과 보청기로 바로 들려주고, 화면에는 자막을 띄웁니다.

01 통역은 이렇게
  1. 마이크로 듣기
  2. 중계 서버로 보내기
  3. Gemini 통역연속
  4. 이어폰·보청기로

영어·일본어·중국어 → 한국어 · 자막에 원문 언어 표시

02 바꾼 것

말이 끊길 때마다 통역 요청

소리를 끊지 않고 계속 흘려 넣기

말 끊김을 찾는 장치를 끄자 약 20초 뒤 멈추던 통역이 이어졌습니다.

03 내가 맡은 것
  • 기획과 문제 정의
  • iOS 앱과 오디오 연결
  • Python 통역 서버
  • AI 초안 코드의 오류 추적과 수정
04 결과연속

약 20초 뒤 멈춤 → 계속 이어지는 통역

실기기 데모 영상 기준 · 지연 시간은 따로 재지 않음

05 보청기 보호 장치
무선 이어폰 그림

보청기가 연결돼 있으면 폰 스피커 전환을 막고, 블루투스가 자리 잡도록 0.8초 기다린 뒤 소리를 켭니다.

오류 기록, 구조, 기술 정보는 원래 페이지에 있습니다.

GitHub 저장소