2016-03-01 3 views
6

ओपनएसएल ईएस का उपयोग कर एंड्रॉइड 6.0.1 चलाने वाले नेक्सस 6 पर कम-विलंबता स्ट्रीमिंग ऑडियो प्लेबैक को लागू करने का प्रयास करते समय मुझे एक अजीब समस्या का सामना करना पड़ रहा है।नेक्सस 6 के साथ एंड्रॉइड - ऐप फोकस से संबंधित ओपनएसएल ऑडियो थ्रेड प्राथमिकता से कैसे बचें?

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

  • "कुछ ही सेकंड" ~ = 3-5 सेकंड, काफी देर तक नहीं एक स्क्रीन परिवर्तन को गति प्रदान करने
  • मेरा आवेदन की गतिविधि सेट FLAG_KEEP_SCREEN_ON, इसलिए कोई स्क्रीन परिवर्तन वैसे भी होने चाहिए
  • मैं, ऑडियो कॉलबैक धागा की प्राथमिकता को बढ़ाने के लिए प्रयास करने के लिए कोई कार्रवाई नहीं की क्योंकि मैं यह धारणा थी कि एंड्रॉयड इन धागों को पहले से ही
  • व्यवहार मेरे नेक्सस 6 (एंड्रॉयड 6.0.1) पर होता है के लिए उच्च प्राथमिकता सुरक्षित रखता है, लेकिन गैलेक्सी एस 6 पर भी उपलब्ध नहीं है (एंड्रॉइड 5.1.1)।

लक्षण जो मैं देख रहा हूं वास्तव में ओएस की तरह लगता है कि फोन के साथ गैर-बातचीत के कुछ सेकंड बाद ऑडियो थ्रेड प्राथमिकता को कम कर देता है। क्या यह सही है? क्या कोई तरीका है कि मैं इस व्यवहार से बच सकता हूं?

+0

एंड्रॉइड 4.4.2 पर चल रहे नेक्सस 5 पर भी नहीं होता है। –

+0

प्लेबैक के दौरान लॉगिंग थ्रेड प्राथमिकता यह दिखाती है कि स्क्रीन टैप करते समय थ्रेड प्राथमिकता वास्तव में बदल नहीं रही है। हो सकता है कि टच इवेंट एक इंटरप्ट को ट्रिगर कर रहा हो जो शेड्यूलर को वापस आने की संभावना है? –

+0

मुझे अपने ऐप्स में एक ही समस्या है। जब तक मैं स्क्रीन से बातचीत करता हूं, तब तक सभी चिकनी चलते हैं। जैसे ही मैं स्क्रीन को छूना बंद कर देता हूं, यह कुछ (लगभग 3-5 सेकंड) के बाद बड़े पैमाने पर ड्रॉप आउट के साथ शुरू होता है। जब मैं स्क्रीन के साथ फिर से बातचीत करना शुरू करता हूं, तो यह सुचारू संचालन पर वापस आ जाता है। इससे कोई फर्क नहीं पड़ता कि स्क्रीन परस्पर क्रिया कुछ वास्तविक है, न ही अगर उंगली एक विशिष्ट नियंत्रण/बटन के साथ ट्रिगर कर रही है। जैसे ही एक उंगली स्क्रीन पर चल रही है, सभी ऑडियो चिकनी चलते हैं। यह एंड्रॉइड 5.x पर नहीं होता है, यह अभी 6.0 के साथ शुरू हुआ है, और यह एंड्रॉइड एन – gal

उत्तर

3

नवीनतम Google I/O 2016 ऑडियो प्रस्तुति को देखते हुए, मुझे अंततः इस समस्या के कारण और (बदसूरत) समाधान मिला।

बस (8m56s से शुरु करके) यह आप ट्यूब क्लिप के चारों ओर एक मिनट देखने के लिए: https://youtu.be/F2ZDp-eNrh4?t=8m56s

यह बताता है कि क्यों यह हो रहा है और आप इसे कैसे से छुटकारा पा सकते है।

वास्तव में, एंड्रॉइड बैटरी उपयोग को कम करने के लिए कुछ सेकंड स्पर्श स्पर्श निष्क्रियता के बाद सीपीयू को धीमा कर देता है। वीडियो में लड़का जल्द ही इसके लिए एक उचित समाधान का वादा करता है, लेकिन अब इसके लिए छुटकारा पाने का एकमात्र तरीका नकली स्पर्श भेजना है (यह आधिकारिक सिफारिश है)।

Instrumentation instr = new Instrumentation(); 
instr.sendKeyDownUpSync(KeyEvent.KEYCODE_BACKSLASH); // or whatever event you prefer 

प्रत्येक 1.5 सेकंड में टाइमर के साथ इसे दोहराएं और समस्या गायब हो जाएगी।

मुझे पता है, यह एक बदसूरत हैक है, और इसमें बदसूरत साइड इफेक्ट्स हो सकते हैं जिन्हें संभाला जाना चाहिए। लेकिन अभी के लिए, यह केवल एकमात्र समाधान है।

अद्यतन: आपकी नवीनतम टिप्पणी के बारे में ... यहां मेरा समाधान है। मैं स्क्रीन सीमाओं के बाहर किसी स्थान पर नियमित MotionEvent.ACTION_DOWN का उपयोग कर रहा हूं। बाकी सब कुछ यूआई के साथ एक अवांछित तरीके से हस्तक्षेप किया। SecurityException से बचने के लिए, मुख्य गतिविधि के ऑनस्टार्ट() हैंडलर में टाइमर प्रारंभ करें और इसे ऑनस्टॉप() हैंडलर में समाप्त करें। ऐसी परिस्थितियां अभी भी होती हैं जब ऐप पृष्ठभूमि में जाता है (सीपीयू लोड के आधार पर) जिसमें आप सुरक्षा अपवाद में भाग ले सकते हैं, इसलिए आपको कोशिश करने वाले ब्लॉक के साथ नकली स्पर्श कॉल को घेरे रखना चाहिए।

कृपया ध्यान दें, कि मैं अपना टाइमर ढांचा का उपयोग कर रहा हूं, इसलिए आपको कोड का उपयोग करने के लिए जो भी टाइमर आप उपयोग करना चाहते हैं उसे बदलने के लिए है।

इसके अलावा, मैं अभी तक सुनिश्चित नहीं कर सकता कि कोड 100% बुलेटप्रूफ है। मेरे ऐप्स में हैक लागू है, लेकिन वर्तमान में बीटा राज्य में है, इसलिए यदि आप सभी उपकरणों और एंड्रॉइड संस्करणों पर सही ढंग से काम कर रहे हैं तो मैं आपको कोई गारंटी नहीं दे सकता।

Timer fakeTouchTimer = null; 
Instrumentation instr; 
void initFakeTouchTimer() 
{ 
    if (this.fakeTouchTimer != null) 
    { 
     if (this.instr == null) 
     { 
      this.instr = new Instrumentation(); 
     } 
     this.fakeTouchTimer.restart(); 
    } 
    else 
    { 
     if (this.instr == null) 
     { 
      this.instr = new Instrumentation(); 
     } 
     this.fakeTouchTimer = new Timer(1500, Thread.MIN_PRIORITY, new TimerTask() 
     { 
      @Override 
      public void execute() 
      { 
       if (instr != null && fakeTouchTimer != null && hasWindowFocus()) 
       { 
        try 
        { 
         long downTime = SystemClock.uptimeMillis(); 

         MotionEvent event = MotionEvent.obtain(downTime, downTime, MotionEvent.ACTION_DOWN, -100, -100, 0); 
         instr.sendPointerSync(event); 
         event.recycle(); 
        } 
        catch (Exception e) 
        { 
        } 
       } 
      } 
     }, true/*isInfinite*/); 
    } 
} 
void killFakeTouchTimer() 
{ 
    if (this.fakeTouchTimer != null) 
    { 
     this.fakeTouchTimer.interupt(); 
     this.fakeTouchTimer = null; 
     this.instr = null; 
    } 
} 

@Override 
protected void onStop() 
{ 
    killFakeTouchTimer(); 
    super.onStop(); 

    ..... 
} 

@Override 
protected void onStart() 
{ 
    initFakeTouchTimer(); 
    super.onStart(); 

    ..... 
} 
+0

उत्तर के लिए धन्यवाद; यह निश्चित रूप से उस मुद्दे की तरह लगता है जिसे मैं दिल में आने की कोशिश कर रहा था। मैंने अपने ऐप को उनके सुझाए गए काम के साथ अपडेट किया है, लेकिन दुर्भाग्य से यह अपेक्षाकृत अधिक हैकिश लगता है। विशेष रूप से, यह सिम्युलेटेड टच इवेंट (कोई क्रॉस-ऐप प्रोग्रामेटिक टच इवेंट नहीं) के दौरान वॉल्यूम चेतावनी आने पर सुरक्षा अपवाद के साथ क्रैश हो सकता है। क्या आपके पास इस के एक और अधिक मजबूत संस्करण को लागू करने का मौका मिला है? –

+1

बदसूरत दुष्प्रभावों के साथ मेरा यही मतलब था। सुरक्षा अपवाद उनमें से एक है। मैंने अपने अंतिम समाधान के साथ अपना जवाब अपडेट कर लिया है। – gal

+1

मैंने अभी देखा है कि मैंने वॉल्यूम चेतावनी (या उसी प्रकृति की अन्य स्थितियों) जैसी परिस्थितियों का ख्याल नहीं रखा है। मैंने उन सभी परिस्थितियों को कवर करने के लिए समाधान को अद्यतन किया। – gal

1

यह अच्छी तरह से ज्ञात है कि the audio pipeline in Android 6 has been completely rewritten। हालांकि अधिकांश मामलों में यह विलंबता से संबंधित मुद्दों में सुधार हुआ है, लेकिन यह असंभव नहीं है कि इसने कई अवांछित साइड इफेक्ट्स उत्पन्न किए हैं, आमतौर पर ऐसे बड़े पैमाने पर परिवर्तनों के मामले में।

आपकी समस्या एक आम एक हो प्रतीत नहीं होता है, वहाँ कुछ चीजें आप की कोशिश करने में सक्षम हो सकते हैं:

  • ऑडियो धागा प्राथमिकता बढ़ाएँ। Android में ऑडियो थ्रेड के लिए डिफ़ॉल्ट प्राथमिकता -16 है, अधिकतम -20 है, आमतौर पर केवल सिस्टम सेवाओं के लिए उपलब्ध होती है। जबकि आप इस मान को ऑडियो थ्रेड पर असाइन नहीं कर सकते हैं, तो आप थ्रेड की प्राथमिकता सेट करते समय ANDROID_PRIORITY_URGENT_AUDIO ध्वज का उपयोग कर अगली सबसे अच्छी चीज़: -19 असाइन कर सकते हैं।

  • किसी भी प्रकार की जिटर या विलंबता को रोकने के लिए बफर की संख्या बढ़ाएं (आप 16 तक भी जा सकते हैं)। हालांकि कुछ उपकरणों पर the callback to fill a new buffer isn’t always called when it should

  • This SO post में एंर्डॉयड पर ऑडियो विलंबता को बेहतर बनाने के लिए कई सुझाव हैं। स्वीकृत उत्तर में विशेष रुचि 3, 4 और 5 अंक हैं।

  • चेक वर्तमान Android प्रणाली कम विलंबता सक्षम पूछताछ की है कि क्या है कि क्या hasSystemFeature(FEATURE_AUDIO_LOW_LATENCY) या hasSystemFeature(FEATURE_AUDIO_PRO)


साथ ही, this academic paper, एंड्रॉयड/OpenSL में ऑडियो विलंबता से संबंधित मुद्दों में सुधार buffer- और कॉलबैक अंतराल से संबंधित दृष्टिकोण सहित के लिए रणनीति पर चर्चा करता है।

+0

उत्तर के लिए धन्यवाद। दुर्भाग्यवश, मैंने पहले से ही इन सभी (बहुत उपयोगी) संसाधनों को पढ़ लिया है और इसमें सुझाई गई तकनीकों को लागू किया है। मैं देशी डिवाइस नमूना दर पर और डिवाइस के मूल बफर आकार पर एक डिवाइस पर चल रहा हूं जो कम विलंबता ऑडियो का समर्थन करने का दावा करता है (असल में, मुझे विश्वास है कि नेक्सस 6 घड़ियों को सबसे छोटे देशी बफर में अभी तक 1 9 2 फ्रेम पर - 48kHz पर 4 एमएस)। आपके द्वारा लिंक किए गए heatvst.com आलेख में वर्णित कारण के लिए बढ़ते बफर नंबर की सहायता नहीं हुई है। मेरा सवाल यह है कि क्यों यूआई इंटरैक्शन ऑडियो प्लेबैक को प्रभावित करता है। –

+0

क्या आपके पास कोई तृतीय-पक्ष ऐप्स स्थापित है जो कुछ सेकंड के गैर-इंटरैक्शन के बाद पृष्ठभूमि में फ़ोकस प्राप्त कर सकता है? – Pickle

+1

कोई ऑडियो थ्रेड 'ANDROID_PRIORITY_URGENT_AUDIO' प्राथमिकता कैसे बनाता है? –

-1

फोर्स

देशी डिवाइस नमूना दर करने के लिए एंड्रॉयड 6. पर resampling उपयोग 48000 उदाहरण के लिए की डिवाइस के मूल नमूना दर:

SLDataFormat_PCM dataFormat;

डेटाफॉर्मैट.samplesPerSec = 48000;

संबंधित मुद्दे