2P by joduchan | ★ favorite | 댓글과 토론

모바일 앱을 만드는 팀이라면 한 번쯤 겪어봤을 겁니다. 테스트 기기는 늘 부족하고, OS 버전을 골고루 커버하기도 어렵습니다. 그렇다고 시뮬레이터를 쓰자니 Xcode나 Android Studio가 필요해서, 기획자·디자이너·서버 개발자처럼 모바일 개발 환경이 없는 팀원은 진입 자체가 막혀 있죠. "샌박에 배포된 거 한 번 봐야 하는데 앱 어떻게 깔아요?" 같은 요청이 올 때마다 모바일 개발자가 하던 일을 멈추고 도와줘야 하죠.

Appetize·BrowserStack도 검토는 했습니다. 다만 (1) 팀 규모가 커질수록 빠르게 오르는 요금과 (2) 앱 바이너리가 외부 클라우드로 업로드되는 구조가 걸려서, 그냥 남는 Mac으로 직접 만들었습니다.

그렇게 만든 게 tapflow 입니다 — 팀 누구나 브라우저에서 iOS 시뮬레이터·Android 에뮬레이터로 모바일 QA를 할 수 있는 오픈소스 셀프호스팅 도구. 보는 쪽은 아무것도 설치할 필요 없이 브라우저만 열면 되고, 셀프호스팅이라 앱 데이터도 팀 Mac 밖으로 나가지 않습니다.

만들면서 가장 어려웠던 건 기능이 아니라 지연(latency)이었습니다. 화면이 반 박자만 밀려도 다들 스크롤 한 번 해보고 닫아버리거든요. 게다가 시뮬레이터 화면은 agent → relay → 브라우저 렌더 파이프를 거치느라 구간마다 지연이 쌓입니다. 이 경로의 지연을 줄이며 정리한 것들입니다:

  • MSE를 버렸습니다. <video> 미디어 버퍼가 구조적으로 ~235ms를 박길래, WebCodecs(보안 컨텍스트)/WASM tinyh264(평문 HTTP) 2-tier로 교체. SPS에 reorder=0을 선언해 decode→present 267ms→2.5ms. (localhost 단일 클럭 측정)
  • 디코더 4개(tinyh264/FFmpeg/openh264)를 벤치마크했지만 결국 tinyh264 유지 — FFmpeg는 정지 화면만 이기고 스크롤에선 매번 지는 데다 번들이 11배. 병목은 디코더가 아니라 부하/전송이었습니다.
  • 안드로이드 SW 인코딩을 Mac의 HW 인코딩으로 개선했습니다. 에뮬레이터엔 HW H.264 인코더가 없어 scrcpy가 SW 인코더에 막힙니다(22–29fps). raw 프레임을 gRPC로 호스트로 빼서 Mac VideoToolbox로 인코딩 → 59fps(다운스케일). (기본 30fps 캡, 실기기는 scrcpy 유지)
  • WDA 없이 iOS 터치(CoreSimulator HID API 직접 주입), Mac Agent는 릴레이로 아웃바운드 연결만(인바운드 방화벽 규칙 불필요).

한계: iOS 에이전트는 macOS 전용, 터치는 Private API라 macOS 업데이트에 깨질 수 있음, 아직 v0.x, 실기기 미지원.

npm install -g tapflow  
tapflow start   # → http://localhost:4000  

MIT 라이선스
GitHub: https://github.com/jo-duchan/tapflow
문서: https://www.tapflow.dev

시뮬레이터 접근 문제를 겪어보신 분, 혹은 저지연 스트리밍/Private API 접근 방식에 대한 의견 환영합니다.

댓글과 토론