Traverba: Aplikasi Flutter dengan 3 Model ASR, LLM Lokal, dan OCR Kamera — Semua Berjalan di Perangkat

Saya membangun Traverba — penerjemah real-time yang berjalan 100% di ponsel tanpa API cloud apa pun. Pengenalan suara, terjemahan ke 108 bahasa, OCR kamera untuk 92 aksara, overlay terjemahan layar, transkripsi file, dan obrolan grup offline melalui Bluetooth untuk hingga 7 orang.

Seluruh aplikasi dibangun dengan Flutter beserta kode platform native untuk pekerjaan berat. Berikut apa yang dilakukan aplikasi ini, mengapa Flutter adalah pilihan tepat, dan tantangan terbesar yang saya hadapi saat merilis ke produksi di iOS dan Android.

Apa yang Dilakukan Aplikasi Ini

Traverba memiliki lima fitur inti, semuanya berjalan secara offline:

Terjemahan Suara Langsung — Bicara dalam satu bahasa, dengar dan baca terjemahannya dalam bahasa lain. Tiga mode tersedia: dalam aplikasi, penangkapan audio sistem mengambang (menerjemahkan audio dari Zoom/Teams/Meet), dan mikrofon mengambang. Pembacaan otomatis dalam bahasa target.

Terjemahan Kamera — Arahkan kamera ke menu, rambu, formulir, atau dokumen. Dua mesin OCR: mode Basic (ML Kit) untuk pembacaan kilat, mode Professional (PaddleOCR) untuk aksara kompleks seperti CJK, Arab, Sirilik, dan Devanagari. Mendukung 92 bahasa. Aplikasi mengganti teks asing dengan teks terjemahan langsung pada gambar.

Terjemahan Layar — Overlay mengambang yang menerjemahkan teks di dalam aplikasi apa pun. Sedang menonton anime, membaca berita Korea, memainkan game Jepang, atau menerima pesan WeChat? Ketuk tombol overlay dan teks langsung diterjemahkan di tempat. Tanpa berpindah aplikasi.

Transkripsi File — Impor file audio atau video (mp3, m4a, wav, mp4) dan dapatkan transkrip berdampingan antara sumber dan terjemahan, lengkap dengan cap waktu.

Obrolan Grup Offline — Hingga 7 orang terhubung melalui jaringan mesh Bluetooth. Setiap orang berbicara dalam bahasanya sendiri. Setiap pesan diterjemahkan ke bahasa semua peserta secara real-time. Tanpa internet. Tanpa server. Setiap ponsel menangani ASR dan terjemahannya sendiri secara mandiri.

Semua ini berjalan secara lokal di prosesor ponsel. Tanpa kunci API, tanpa biaya server, tanpa data yang meninggalkan perangkat.

Mengapa Flutter

Saya mengevaluasi Flutter, React Native, dan native penuh (kode Swift + Kotlin terpisah) di awal.

Lintas platform dari satu basis kode adalah keharusan mutlak. Seorang pengembang tunggal yang memelihara dua basis kode native untuk aplikasi sekompleks ini adalah hal yang tidak realistis. Lapisan UI Dart — pengaturan, gelembung obrolan, tampilan transkrip, tur orientasi, lembar unduhan, pemilih bahasa — mencakup sekitar 60% dari total kode. Menulis semuanya dua kali akan menggandakan jadwal proyek.

Sistem platform channel Flutter membuat integrasi native menjadi praktis. Pekerjaan berat yang melibatkan AI (inferensi ASR, terjemahan LLM, OCR, mesh Bluetooth, overlay mengambang) berjalan di Swift/Kotlin native melalui platform channel dan method channel. Flutter tidak mencoba menjadi runtime AI — Flutter adalah lapisan UI dan orkestrasi yang menghubungkan mesin-mesin native.

Performa sudah lebih dari cukup. Kekhawatiran dengan Flutter untuk aplikasi seperti ini adalah overhead — setiap milidetik berarti ketika Anda menghubungkan ASR → terjemahan → TTS dalam percakapan. Dalam praktiknya, lapisan Flutter menambahkan latensi yang dapat diabaikan karena komputasi berat terjadi di kode native. Lapisan Dart menangani manajemen state, perutean, dan pembaruan UI — dan ia melakukannya dengan baik.

Hot reload mempercepat iterasi UI secara dramatis. Dengan lima permukaan fitur yang berbeda (suara, kamera, layar, file, obrolan grup), masing-masing dengan berbagai state dan mode, kemampuan untuk mengiterasi UI tanpa harus membangun ulang adalah pengganda produktivitas yang signifikan.

Arsitektur: Flutter sebagai Orkestrator

Aplikasi mengikuti pemisahan yang jelas:

Lapisan Flutter/Dart menangani:

  • Semua UI (Material 3, tata letak adaptif untuk ponsel dan tablet)
  • Manajemen state dan perutean fitur
  • Pemilihan bahasa/lokal dan preferensi pengguna
  • Manajemen unduhan untuk model opsional
  • Ekonomi koin dan pembatasan langganan
  • Tur panduan orientasi

Lapisan native menangani (melalui platform channel):

  • Inferensi ASR (sherpa-onnx / whisper.cpp)
  • Terjemahan LLM (Gemma melalui runtime on-device)
  • Terjemahan ML tradisional (model NMT ONNX)
  • OCR kamera (ML Kit + PaddleOCR)
  • Text-to-speech
  • Mesh Bluetooth untuk obrolan grup
  • Overlay mengambang (terjemahan layar + penangkapan audio sistem)
  • Manajemen anggaran memori dan pemuatan/pengeluaran model

Jembatan antara lapisan-lapisan ini adalah sekumpulan platform channel dengan kontrak yang terdefinisi dengan baik. Sisi Dart mengirim perintah ("mulai ASR untuk Kanton," "terjemahkan teks ini dari Jepang ke Inggris," "tangkap layar dan OCR"). Sisi native mengembalikan hasil secara asinkron.

Tiga Model ASR, Perutean Otomatis

Tidak ada satu model pengenalan suara yang cocok untuk semua bahasa. Alih-alih menerima kualitas buruk untuk sebagian bahasa, aplikasi ini menyertakan tiga model khusus:

  • Parakeet Dioptimalkan untuk bahasa Inggris. Disertakan bersama aplikasi untuk ASR Inggris instan tanpa unduhan.
  • Whisper.cpp Cakupan multibahasa luas mencakup 30+ bahasa.
  • Qwen3-ASR Dioptimalkan untuk CJK dengan dukungan khusus untuk bahasa Kanton.

Ketika pengguna memilih bahasa sumber, lapisan perutean Dart memilih model terbaik dan memberi tahu sisi native mesin mana yang harus diaktifkan. Pengguna tidak pernah melihat atau mengelola pemilihan model.

Bagian yang rumit adalah memori. Model-model ini berkisar antara 500MB hingga 1,9GB dalam RAM. Memuat ketiga model secara bersamaan akan membuat sebagian besar ponsel crash. Perencana anggaran memori (ditulis dalam Dart, mengkueri statistik memori native) melacak apa yang dimuat dan mengeluarkan model yang paling jarang digunakan ketika model baru perlu dimuat. Penyimpan preferensi backend mengingat backend komputasi mana (NPU, GPU, CPU) yang berhasil digunakan pada perangkat tertentu, sehingga proses berikutnya melewati backend yang gagal.

108 Bahasa melalui Dua Tingkatan Terjemahan

Terjemahan terjadi melalui dua jalur:

Tingkatan 1 — Model NMT tradisional (61 bahasa): Cepat, konsumsi memori rendah, kualitas baik untuk pasangan bahasa yang kaya sumber daya. Model ONNX berjalan melalui sherpa-onnx di kedua platform.

Tingkatan 2 — Gemma LLM on-device (47 bahasa tambahan): Untuk bahasa-bahasa tanpa model NMT khusus (Yoruba, Amharik, Lao, Myanmar, dan lainnya), model Gemma 2B yang dikuantisasi menangani terjemahan secara lokal. Lebih lambat dari Tingkatan 1, tetapi memperluas cakupan ke bahasa-bahasa yang model tradisional tidak layani dengan baik.

Lapisan Dart mengelola tingkatan mana yang digunakan berdasarkan pasangan bahasa. Pengguna merasakan pengalaman yang terpadu.

OCR Kamera: Mesin Ganda, 92 Bahasa

Terjemahan kamera menjalankan dua mesin yang dapat dipilih pengguna:

Mode Basic menggunakan pengenalan teks on-device dari Google ML Kit. Cepat, menangani Latin, Sirilik, dan CJK dengan baik. Cocok untuk penggunaan viewfinder real-time.

Mode Professional menggunakan PaddleOCR yang berjalan di perangkat. Akurasi lebih baik untuk tata letak kompleks, aksara campuran, teks melengkung, dan kontras rendah. Menggunakan gerbang koin (5 koin per tangkapan) karena lebih intensif secara komputasi.

Satu pelajaran yang dipelajari dengan susah payah: iOS hanya menyertakan model aksara OCR Latin secara default. CJK, Devanagari, dan Arab memerlukan penambahan pod khusus aksara ke Podfile secara eksplisit. Kegagalannya sepenuhnya senyap — ML Kit mengembalikan hasil kosong untuk aksara yang tidak didukung tanpa pesan error. Jika Anda membangun OCR multibahasa di iOS dengan ML Kit, periksa Podfile Anda.

Overlay Mengambang: Native, Bukan Flutter

Fitur terjemahan layar dan audio sistem berjalan sebagai overlay native di luar permukaan rendering Flutter. Di Android, ini adalah layanan overlay sistem yang ditulis dalam Kotlin. Di iOS, menggunakan API tangkapan layar di Swift.

Overlay-overlay ini berkomunikasi kembali ke mesin terjemahan Flutter melalui platform channel. Tantangan arsitekturalnya adalah manajemen siklus hidup — overlay harus tetap hidup sementara aktivitas Flutter utama mungkin sedang berjalan di latar belakang.

Satu pelajaran kritis: di iOS, instance jembatan native harus dipertahankan dengan kuat (static atau dipegang oleh singleton). Jika jembatan adalah variabel instance yang tidak dipertahankan oleh apa pun, ARC akan mengumpulkan sampahnya dan semua closure handler secara senyap menjadi tidak berfungsi. Saya kehilangan berhari-hari karena indikator progres unduhan terhenti di 0% akibat jembatan yang dikumpulkan. Tidak ada crash, tidak ada error, hanya kegagalan senyap.

Obrolan Grup Bluetooth

Obrolan grup offline menggunakan protokol mesh Bluetooth. Setiap ponsel bertindak sebagai penerima sekaligus relai. Pesan disiarkan ke semua perangkat yang terhubung. Setiap perangkat menjalankan ASR dan terjemahannya sendiri secara mandiri — tidak ada ponsel "host" atau "server".

Flutter menangani UI obrolan, state pesan, dan manajemen peserta. Tumpukan Bluetooth sepenuhnya native (CoreBluetooth di iOS, Android Bluetooth API) yang dijembatani melalui platform channel.

Total latensi pipeline (suara → ASR → terjemahan → siaran → tampilan) sekitar 1 detik. UI Dart menggunakan tampilan optimistis (menampilkan "sedang menerjemahkan..." segera saat pengiriman) sehingga percakapan terasa responsif.

Angka-angka

  • Bahasa: 108 total (61 ML + 47 AI)
  • Bahasa ASR: 30 pengenalan suara on-device
  • Bahasa OCR: 92 pengenalan teks kamera
  • Ukuran dasar aplikasi: ~150MB + model yang dapat diunduh
  • Platform: iOS + Android dari satu basis kode Flutter
  • Kode Dart/Flutter: ~60% dari total basis kode (UI, state, perutean, logika bisnis)
  • Kode native: ~40% (ASR, LLM, OCR, Bluetooth, overlay, manajemen memori)
  • Ukuran tim: 1

Yang Flutter Lakukan dengan Tepat untuk Proyek Ini

Satu basis kode untuk UI yang kompleks. Lima permukaan fitur, masing-masing dengan beberapa mode, lembar unduhan, tur orientasi, tata letak adaptif — menulis ini sekali alih-alih dua kali adalah perbedaan antara rilis dan tidak rilis sebagai pengembang tunggal.

Platform channel dirancang dengan baik. Jembatan antara Dart dan kode native bersih, terdokumentasi dengan baik, dan andal. Untuk aplikasi di mana komputasi berat adalah native tetapi pengalaman pengguna adalah Flutter, ini adalah arsitektur yang tepat.

Hot reload untuk iterasi cepat. Menyetel tata letak, menguji state, mengiterasi alur UX — hot reload memangkas waktu iterasi dari menit menjadi detik di ratusan perubahan UI.

Ekosistemnya sudah matang. Manajemen state (Riverpod), navigasi, lokalisasi (117 lokal), desain adaptif — ekosistem Flutter memiliki solusi berkualitas produksi untuk semua ini.

Yang Sulit

Tekanan memori adalah titik buta Flutter. Flutter tidak mengekspos kontrol memori yang terperinci. Ketika Anda memuat beberapa model ML native secara bersamaan bersama mesin Flutter, Anda perlu mengelola memori di tingkat native dan menyampaikannya kembali ke Dart. Tidak ada API Flutter bawaan untuk "berapa banyak RAM yang digunakan aplikasi saya" atau "berapa tekanan memori sistem saat ini."

Siklus hidup overlay native. Overlay mengambang yang beroperasi di luar permukaan Flutter secara arsitektural sangat kompleks. Aktivitas Flutter mungkin berjalan di latar belakang sementara overlay sedang aktif. Menjaga jembatan tetap hidup, mengelola sinkronisasi state, dan menangani event siklus hidup spesifik platform memerlukan kode native yang signifikan yang tidak dapat diabstraksikan oleh Flutter.

Kompleksitas build iOS. CocoaPods dengan pod aksara ML Kit, entitlemen (increased-memory-limit untuk memuat ASR + LLM secara bersamaan), waktu App Tracking Transparency, penandatanganan kode — pipeline build iOS memiliki banyak bagian bergerak yang tidak sepenuhnya dikelola oleh tooling Flutter.

Coba Sekarang

Traverba gratis di kedua platform. Terjemahan suara, kamera, layar, dan teks semuanya gratis dan tidak terbatas. Premium ($1.99/bulan) membuka obrolan grup, transkripsi file, dan ringkasan rapat.

Tersedia di Google Play dan App Store. Pelajari lebih lanjut di traverba.com.

Saya senang menjawab pertanyaan tentang arsitektur, pola integrasi Flutter + native, atau AI on-device secara umum.