Traverba: एक Flutter ऐप जो 3 ASR मॉडल, एक लोकल LLM, और कैमरा OCR चलाता है — सब कुछ ऑन-डिवाइस

मैंने Traverba बनाया — एक रियल-टाइम ट्रांसलेटर जो 100% आपके फ़ोन पर चलता है, बिना किसी क्लाउड API के। आवाज़ पहचान, 108 भाषाओं में अनुवाद, 92 लिपियों में कैमरा OCR, स्क्रीन ट्रांसलेशन ओवरले, फ़ाइल ट्रांसक्रिप्शन, और Bluetooth पर ऑफलाइन ग्रुप चैट — एक साथ 7 लोगों के लिए।

पूरा ऐप Flutter के साथ बनाया गया है, और भारी काम के लिए नेटिव प्लेटफॉर्म कोड का इस्तेमाल किया गया है। यहाँ बताया गया है कि ऐप क्या करता है, Flutter सही विकल्प क्यों था, और iOS व Android दोनों पर प्रोडक्शन में शिप करते समय मुझे किन बड़ी चुनौतियों का सामना करना पड़ा।

ऐप क्या करता है

Traverba में पाँच मुख्य फीचर हैं, सभी ऑफलाइन चलते हैं:

लाइव वॉयस ट्रांसलेशन — एक भाषा में बोलें, दूसरी भाषा में अनुवाद सुनें और पढ़ें। तीन मोड: इन-ऐप, फ्लोटिंग सिस्टम ऑडियो कैप्चर (Zoom/Teams/Meet का ऑडियो ट्रांसलेट करता है), और फ्लोटिंग माइक्रोफोन। टार्गेट भाषा में ऑटो रीड-अलाउड।

कैमरा ट्रांसलेशन — किसी मेन्यू, साइनबोर्ड, फॉर्म या दस्तावेज़ पर कैमरा पॉइंट करें। दो OCR इंजन: Basic मोड (ML Kit) त्वरित रीडिंग के लिए, Professional मोड (PaddleOCR) CJK, अरबी, सिरिलिक, और देवनागरी जैसी जटिल लिपियों के लिए। 92 भाषाओं को सपोर्ट करता है। ऐप इमेज पर विदेशी टेक्स्ट को सीधे अनुवादित टेक्स्ट से बदल देता है।

स्क्रीन ट्रांसलेशन — एक फ्लोटिंग ओवरले जो किसी भी ऐप के अंदर के टेक्स्ट का अनुवाद करता है। एनीमे देख रहे हैं, कोरियाई न्यूज़ पढ़ रहे हैं, जापानी गेम खेल रहे हैं, या WeChat मैसेज मिला है? ओवरले बटन टैप करें और टेक्स्ट वहीं अनुवादित हो जाएगा। कोई ऐप स्विचिंग नहीं।

फ़ाइल ट्रांसक्रिप्शन — ऑडियो या वीडियो फ़ाइलें (mp3, m4a, wav, mp4) इंपोर्ट करें और टाइमस्टैंप सहित, साइड-बाय-साइड सोर्स + ट्रांसलेटेड ट्रांसक्रिप्ट पाएं।

ऑफलाइन ग्रुप चैट — 7 लोग तक Bluetooth मेश के ज़रिए कनेक्ट होते हैं। हर व्यक्ति अपनी भाषा में बोलता है। हर मैसेज रियल टाइम में हर प्रतिभागी की भाषा में अनुवादित होता है। कोई इंटरनेट नहीं। कोई सर्वर नहीं। हर फ़ोन अपना ASR और ट्रांसलेशन खुद संभालता है।

यह सब फ़ोन के प्रोसेसर पर लोकली चलता है। कोई API कीज़ नहीं, कोई सर्वर खर्च नहीं, डिवाइस से बाहर कोई डेटा नहीं जाता।

Flutter क्यों

मैंने शुरुआत में Flutter, React Native, और पूरी तरह नेटिव (अलग Swift + Kotlin कोडबेस) का मूल्यांकन किया।

एक सिंगल कोडबेस से क्रॉस-प्लेटफॉर्म होना ज़रूरी था। एक सोलो डेवलपर के लिए इतने जटिल ऐप के लिए दो नेटिव कोडबेस मेंटेन करना व्यावहारिक नहीं था। Dart UI लेयर — सेटिंग्स, चैट बबल, ट्रांसक्रिप्ट व्यू, ऑनबोर्डिंग टूर, डाउनलोड शीट्स, लैंग्वेज पिकर — कुल कोड का लगभग 60% है। इसे दो बार लिखना प्रोजेक्ट की समयसीमा दोगुनी कर देता।

Flutter के प्लेटफॉर्म चैनल सिस्टम ने नेटिव इंटीग्रेशन को व्यावहारिक बनाया। AI-भारी काम (ASR inference, LLM ट्रांसलेशन, OCR, Bluetooth मेश, फ्लोटिंग ओवरले) प्लेटफॉर्म चैनल और मेथड चैनल के ज़रिए नेटिव Swift/Kotlin में चलता है। Flutter AI रनटाइम नहीं है — यह UI और ऑर्केस्ट्रेशन लेयर है जो नेटिव इंजनों को जोड़ती है।

परफॉर्मेंस पर्याप्त अच्छी थी। इस तरह के ऐप के लिए Flutter को लेकर चिंता ओवरहेड की होती है — जब आप किसी कन्वर्सेशन में ASR → ट्रांसलेशन → TTS चेन कर रहे हों तो हर मिलीसेकंड मायने रखता है। व्यवहार में, Flutter लेयर नगण्य लेटेंसी जोड़ती है क्योंकि भारी कम्प्यूटेशन नेटिव कोड में होती है। Dart लेयर स्टेट मैनेजमेंट, रूटिंग, और UI अपडेट संभालती है, जो वह अच्छी तरह करती है।

Hot reload ने UI इटरेशन को बहुत तेज़ कर दिया। पाँच अलग-अलग फीचर सर्फेस (वॉयस, कैमरा, स्क्रीन, फ़ाइल, ग्रुप चैट) के साथ, हर एक के कई स्टेट और मोड के साथ, रीबिल्ड किए बिना UI पर इटरेट करने की क्षमता एक बड़ा प्रोडक्टिविटी मल्टीप्लायर था।

आर्किटेक्चर: Flutter बतौर ऑर्केस्ट्रेटर

ऐप एक स्पष्ट विभाजन का पालन करता है:

Flutter/Dart लेयर संभालती है:

  • सारी UI (Material 3, फ़ोन और टैबलेट के लिए adaptive layouts)
  • स्टेट मैनेजमेंट और फीचर रूटिंग
  • भाषा/लोकेल चयन और यूज़र प्रेफरेंस
  • वैकल्पिक मॉडल के लिए डाउनलोड मैनेजमेंट
  • कॉइन इकोनॉमी और सब्सक्रिप्शन गेटिंग
  • ऑनबोर्डिंग गाइडेड टूर

नेटिव लेयर संभालती है (प्लेटफॉर्म चैनल के ज़रिए):

  • ASR inference (sherpa-onnx / whisper.cpp)
  • LLM ट्रांसलेशन (ऑन-डिवाइस रनटाइम के ज़रिए Gemma)
  • ट्रेडिशनल ML ट्रांसलेशन (ONNX NMT मॉडल)
  • कैमरा OCR (ML Kit + PaddleOCR)
  • टेक्स्ट-टू-स्पीच
  • ग्रुप चैट के लिए Bluetooth मेश
  • फ्लोटिंग ओवरले (स्क्रीन ट्रांसलेशन + सिस्टम ऑडियो कैप्चर)
  • मेमोरी बजट मैनेजमेंट और मॉडल लोडिंग/इवेक्शन

इन लेयरों के बीच का ब्रिज प्लेटफॉर्म चैनलों का एक सेट है जिनके स्पष्ट रूप से परिभाषित कॉन्ट्रैक्ट हैं। Dart साइड कमांड भेजती है ("कैंटोनीज़ के लिए ASR शुरू करो," "जापानी से अंग्रेज़ी में यह टेक्स्ट ट्रांसलेट करो," "स्क्रीन कैप्चर करो और OCR करो")। नेटिव साइड एसिंक्रोनसली रिज़ल्ट लौटाती है।

तीन ASR मॉडल, ऑटोमैटिक रूटिंग

कोई एक स्पीच रिकग्निशन मॉडल सभी भाषाओं को अच्छी तरह कवर नहीं करता। कुछ भाषाओं के लिए खराब गुणवत्ता स्वीकार करने की बजाय, ऐप तीन स्पेशलाइज़्ड मॉडल शिप करता है:

  • Parakeet अंग्रेज़ी के लिए ऑप्टिमाइज़्ड। बिना किसी डाउनलोड के तत्काल अंग्रेज़ी ASR के लिए ऐप के साथ बंडल।
  • Whisper.cpp 30+ भाषाओं में व्यापक बहुभाषी कवरेज।
  • Qwen3-ASR डेडिकेटेड कैंटोनीज़ सपोर्ट के साथ CJK के लिए ऑप्टिमाइज़्ड।

जब यूज़र सोर्स भाषा चुनता है, तो Dart रूटिंग लेयर सबसे अच्छा मॉडल चुनती है और नेटिव साइड को बताती है कि कौन सा इंजन एक्टिवेट करना है। यूज़र को मॉडल चयन कभी दिखता या मैनेज नहीं करना पड़ता।

पेचीदा हिस्सा मेमोरी है। ये मॉडल RAM में 500MB से 1.9GB तक होते हैं। तीनों को एक साथ लोड करने से ज़्यादातर फ़ोन क्रैश हो जाएंगे। एक मेमोरी बजट प्लानर (Dart में लिखा गया, नेटिव मेमोरी स्टैट्स क्वेरी करता है) ट्रैक करता है कि क्या लोड है और जब कोई नया मॉडल लोड होना हो तो सबसे कम हाल ही में इस्तेमाल किए गए मॉडल को इवेक्ट करता है। एक बैकएंड प्रेफरेंस स्टोर याद रखता है कि किस कम्प्यूट बैकएंड (NPU, GPU, CPU) ने किस स्पेसिफिक डिवाइस पर काम किया, ताकि बाद के रन में फेल बैकएंड छोड़ दिए जाएं।

दो ट्रांसलेशन टायर के ज़रिए 108 भाषाएं

ट्रांसलेशन दो रास्तों से होता है:

Tier 1 — ट्रेडिशनल NMT मॉडल (61 भाषाएं): तेज़, कम मेमोरी, अच्छी तरह से सपोर्टेड भाषा जोड़ों के लिए अच्छी गुणवत्ता। दोनों प्लेटफॉर्म पर sherpa-onnx के ज़रिए चलने वाले ONNX मॉडल।

Tier 2 — ऑन-डिवाइस Gemma LLM (47 अतिरिक्त भाषाएं): उन भाषाओं के लिए जिनके पास डेडिकेटेड NMT मॉडल नहीं हैं (योरूबा, अम्हारिक, लाओ, म्यांमार, और अन्य), एक quantized Gemma 2B मॉडल लोकली ट्रांसलेशन संभालता है। Tier 1 से धीमा, लेकिन यह उन भाषाओं तक कवरेज बढ़ाता है जिन्हें ट्रेडिशनल मॉडल कम अच्छी तरह सर्व करते हैं।

Dart लेयर मैनेज करती है कि भाषा जोड़ी के आधार पर कौन सा टायर इस्तेमाल करना है। यूज़र को एक एकीकृत अनुभव मिलता है।

कैमरा OCR: डुअल इंजन, 92 भाषाएं

कैमरा ट्रांसलेशन दो इंजन चलाता है जिन्हें यूज़र चुन सकता है:

Basic मोड Google ML Kit की ऑन-डिवाइस टेक्स्ट रिकग्निशन का इस्तेमाल करता है। तेज़, Latin, Cyrillic, और CJK को अच्छी तरह हैंडल करता है। रियल-टाइम व्यूफाइंडर उपयोग के लिए अच्छा।

Professional मोड ऑन-डिवाइस चलने वाले PaddleOCR का इस्तेमाल करता है। जटिल लेआउट, मिश्रित लिपियों, घुमावदार टेक्स्ट, और कम कंट्रास्ट के लिए बेहतर सटीकता। कॉइन गेट का इस्तेमाल करता है (5 कॉइन प्रति कैप्चर) क्योंकि यह अधिक कम्प्यूट-इंटेंसिव है।

एक कड़वा सबक: iOS डिफ़ॉल्ट रूप से केवल Latin OCR स्क्रिप्ट मॉडल बंडल करता है। CJK, Devanagari, और अरबी के लिए Podfile में स्क्रिप्ट-स्पेसिफिक pods को एक्सप्लिसिटली जोड़ना ज़रूरी है। यह विफलता पूरी तरह साइलेंट है — ML Kit बिना किसी एरर के असपोर्टेड लिपियों के लिए खाली रिज़ल्ट लौटाता है। अगर आप iOS पर ML Kit के साथ मल्टीलिंगुअल OCR बना रहे हैं, तो अपना Podfile ज़रूर जांचें।

फ्लोटिंग ओवरले: Flutter नहीं, नेटिव

स्क्रीन ट्रांसलेशन और सिस्टम ऑडियो फीचर Flutter की रेंडरिंग सर्फेस के बाहर नेटिव ओवरले के रूप में चलते हैं। Android पर, यह Kotlin में लिखी गई एक सिस्टम ओवरले सर्विस है। iOS पर, यह Swift में स्क्रीन कैप्चर APIs का इस्तेमाल करता है।

ये ओवरले प्लेटफॉर्म चैनलों के ज़रिए Flutter ट्रांसलेशन इंजन को वापस कम्युनिकेट करते हैं। आर्किटेक्चरल चुनौती लाइफसाइकल मैनेजमेंट है — ओवरले को तब भी ज़िंदा रहना होगा जब मुख्य Flutter एक्टिविटी बैकग्राउंड में हो।

एक महत्वपूर्ण सबक: iOS पर, नेटिव ब्रिज इंस्टेंस को स्ट्रॉन्गली रिटेन (static या किसी singleton द्वारा होल्ड) किया जाना चाहिए। अगर ब्रिज एक इंस्टेंस वेरिएबल है जिसे कुछ भी रिटेन नहीं करता, तो ARC इसे गार्बेज-कलेक्ट कर देगा और सभी हैंडलर क्लोज़र साइलेंटली no-ops बन जाएंगे। मैंने इस वजह से एक डाउनलोड प्रोग्रेस इंडिकेटर 0% पर अटके रहने के कारण कई दिन गंवाए क्योंकि ब्रिज कलेक्ट हो रहा था। कोई क्रैश नहीं, कोई एरर नहीं, बस साइलेंट फेलियर।

Bluetooth ग्रुप चैट

ऑफलाइन ग्रुप चैट एक Bluetooth मेश प्रोटोकॉल का इस्तेमाल करता है। हर फ़ोन रिसीवर और रिले दोनों की तरह काम करता है। मैसेज सभी कनेक्टेड डिवाइसों पर ब्रॉडकास्ट होते हैं। हर डिवाइस अपना ASR और ट्रांसलेशन स्वतंत्र रूप से चलाता है — कोई "होस्ट" या "सर्वर" फ़ोन नहीं है।

Flutter चैट UI, मैसेज स्टेट, और प्रतिभागी मैनेजमेंट संभालता है। Bluetooth स्टैक पूरी तरह नेटिव है (iOS पर CoreBluetooth, Android Bluetooth API) जो प्लेटफॉर्म चैनलों के ज़रिए ब्रिज किया गया है।

कुल पाइपलाइन लेटेंसी (आवाज़ → ASR → ट्रांसलेट → ब्रॉडकास्ट → डिस्प्ले) लगभग 1 सेकंड है। Dart UI ऑप्टिमिस्टिक डिस्प्ले का इस्तेमाल करता है (सेंड पर तुरंत "translating..." दिखाएं) ताकि कन्वर्सेशन रिस्पॉन्सिव लगे।

आंकड़े

  • भाषाएं: 108 कुल (61 ML + 47 AI)
  • ASR भाषाएं: 30 ऑन-डिवाइस स्पीच रिकग्निशन
  • OCR भाषाएं: 92 कैमरा टेक्स्ट रिकग्निशन
  • ऐप बेस साइज़: ~150MB + डाउनलोडेबल मॉडल
  • प्लेटफॉर्म: एकल Flutter कोडबेस से iOS + Android
  • Dart/Flutter कोड: कुल कोडबेस का ~60% (UI, स्टेट, रूटिंग, बिज़नेस लॉजिक)
  • नेटिव कोड: ~40% (ASR, LLM, OCR, Bluetooth, ओवरले, मेमोरी मैनेजमेंट)
  • टीम साइज़: 1

इस प्रोजेक्ट में Flutter ने क्या सही किया

जटिल UI के लिए सिंगल कोडबेस। पाँच फीचर सर्फेस, हर एक के कई मोड, डाउनलोड शीट्स, ऑनबोर्डिंग टूर, adaptive layouts — इसे एक बार की बजाय दो बार लिखना एक सोलो डेवलपर के रूप में शिप करने और न करने के बीच का फ़र्क था।

प्लेटफॉर्म चैनल अच्छी तरह डिज़ाइन किए गए हैं। Dart और नेटिव कोड के बीच का ब्रिज साफ़, अच्छी तरह डॉक्युमेंटेड, और विश्वसनीय है। ऐसे ऐप के लिए जहाँ भारी कम्प्यूट नेटिव है लेकिन यूज़र एक्सपीरियंस Flutter है, यह बिल्कुल सही आर्किटेक्चर है।

तेज़ इटरेशन के लिए Hot reload। लेआउट ट्यून करना, स्टेट टेस्ट करना, UX फ्लो पर इटरेट करना — hot reload ने सैकड़ों UI बदलावों में इटरेशन टाइम को मिनटों से सेकंड में कम कर दिया।

इकोसिस्टम मेच्योर है। स्टेट मैनेजमेंट (Riverpod), नेविगेशन, लोकलाइज़ेशन (117 लोकेल), adaptive डिज़ाइन — Flutter इकोसिस्टम में इन सभी के लिए प्रोडक्शन-क्वालिटी सॉल्यूशन हैं।

क्या मुश्किल था

मेमोरी प्रेशर Flutter का कमज़ोर पक्ष है। Flutter फाइन-ग्रेन्ड मेमोरी कंट्रोल एक्सपोज़ नहीं करता। जब आप Flutter इंजन के साथ कई नेटिव ML मॉडल को-लोड कर रहे होते हैं, तो आपको नेटिव स्तर पर मेमोरी मैनेज करनी होती है और उसे Dart को वापस सर्फेस करना होता है। "मेरा ऐप कितनी RAM इस्तेमाल कर रहा है" या "सिस्टम मेमोरी प्रेशर क्या है" के लिए कोई बिल्ट-इन Flutter API नहीं है।

नेटिव ओवरले लाइफसाइकल। Flutter सर्फेस के बाहर चलने वाले फ्लोटिंग ओवरले आर्किटेक्चरली जटिल हैं। ओवरले एक्टिव होने पर Flutter एक्टिविटी बैकग्राउंड में हो सकती है। ब्रिज को ज़िंदा रखना, स्टेट सिंक्रोनाइज़ेशन मैनेज करना, और प्लेटफॉर्म-स्पेसिफिक लाइफसाइकल इवेंट हैंडल करना — इन सबके लिए महत्वपूर्ण नेटिव कोड की ज़रूरत पड़ी जिसे Flutter एब्सट्रैक्ट नहीं कर सकता।

iOS बिल्ड की जटिलता। ML Kit स्क्रिप्ट pods के साथ CocoaPods, entitlements (ASR + LLM को-लोड करने के लिए increased-memory-limit), App Tracking Transparency टाइमिंग, कोड साइनिंग — iOS बिल्ड पाइपलाइन में कई मूविंग पार्ट्स हैं जिन्हें Flutter का टूलिंग पूरी तरह मैनेज नहीं करता।

आज़माएं

Traverba दोनों प्लेटफॉर्म पर मुफ्त है। वॉयस, कैमरा, स्क्रीन ट्रांसलेशन, और टेक्स्ट ट्रांसलेशन सभी मुफ्त और अनलिमिटेड हैं। Premium ($1.99/महीना) ग्रुप चैट, फ़ाइल ट्रांसक्रिप्शन, और मीटिंग सारांश अनलॉक करता है।

Google Play और App Store पर उपलब्ध है। traverba.com पर अधिक जानें।

आर्किटेक्चर, Flutter + नेटिव इंटीग्रेशन पैटर्न, या सामान्य रूप से ऑन-डिवाइस AI के बारे में सवालों का जवाब देने में मुझे खुशी होगी।