2013-05-06 6 views
8

मैं दूरस्थ सर्वर से ऑडियो चलाने के लिए एक एप्लिकेशन लिख रहा हूं। मैंने स्ट्रीमिंग ऑडियो को लागू करने के कई तरीकों की कोशिश की, लेकिन वे सभी मेरे लिए पर्याप्त नहीं हैं। यही तो मैं करने की कोशिश की है या नहीं: MediaPlayer का उपयोग करते हुएऑडियो स्ट्रीमिंग के लिए सर्वोत्तम अभ्यास

अनुभवहीन

कुछ की तरह:

MediaPlayer player = new MediaPlayer(); 
player.setDataSource(context, Uri.parse("http://whatever.com/track.mp3")); 
player.prepare(); 
player.start(); 

(या prepareAsync, कोई फर्क नहीं पड़ता)

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

को लागू कस्टम बफरिंग

तो फिर वहाँ एक विचार, मात्रा द्वारा मीडिया फाइल डाउनलोड उन्हें एक स्थानीय फ़ाइल में गठबंधन और इस फाइल को खेलने के लिए बन गया। खराब कनेक्शन के कारण पूरी फ़ाइल को डाउनलोड करना धीमा हो सकता है, इसलिए शुरुआती टुकड़े को डाउनलोड करना ठीक होगा, फिर प्लेबैक शुरू करें और स्थानीय फ़ाइल डाउनलोड करना और जोड़ना जारी रखें। इसके अलावा, हमें कैशिंग कार्यक्षमता मिलती है।

एक योजना की तरह लगता है, लेकिन यह हमेशा काम नहीं करता था। यह एचटीसी सेंसेशन एक्सई पर पूरी तरह से काम करता है लेकिन 4.1 प्रारंभिक टुकड़े को खत्म करने के बाद 4.1 टैबलेट प्लेबैक पर नहीं चला। पता नहीं, ऐसा क्यों है। मैंने इस बारे में question से पूछा है, लेकिन कोई जवाब नहीं मिला है।

दो मीडिया प्लेयर्स

मैं दो MediaPlayer उदाहरणों बनाया और उन्हें एक दूसरे को बदलने बनाने के लिए कोशिश की है का उपयोग करना। तर्क पीछा कर रहा है:

  • प्रारंभ मीडिया के प्रारंभिक भाग को डाउनलोड
  • जब इसे डाउनलोड किया है, currentMediaPlayer के माध्यम से प्लेबैक शुरू। मीडिया के बाकी जारी है
  • जब डाउनलोड किया टुकड़ा लगभग खेला जाता है (समाप्त होने से पहले 1 सेकंड) को डाउनलोड करने, एक ही स्रोत फ़ाइल के साथ secondaryMediaPlayer तैयार (के रूप में यह प्लेबैक के दौरान संलग्न की गई) currentMediaPlayer के अंत से पहले
  • 261 एमएस - यह थामने , माध्यमिक शुरू करें, वर्तमान माध्यमिक सेट करें, अगले माध्यमिक खिलाड़ी की तैयारी शेड्यूल करें।

स्रोत:

private static final String FILE_NAME="local.mp3"; 
private static final String URL = ...; 
private static final long FILE_SIZE = 7084032; 

private static final long PREPARE_NEXT_PLAYER_OFFSET = 1000; 
private static final int START_NEXT_OFFSET = 261; 

private static final int INIT_PERCENTAGE = 3; 

private MediaPlayer mPlayer; 
private MediaPlayer mSecondaryPlayer; 

private Handler mHandler = new Handler(); 

public void startDownload() { 
    mDownloader = new Mp3Downloader(FILE_NAME, URL, getExternalCacheDir()); 
    mDownloader.setDownloadListener(mInitDownloadListener); 
    mDownloader.startDownload(); 
} 


private Mp3Downloader.DownloadListener mInitDownloadListener = new Mp3Downloader.DownloadListener() { 
    public void onDownloaded(long bytes) { 
     int percentage = Math.round(bytes * 100f/FILE_SIZE); 

     // Start playback when appropriate piece of media downloaded 
     if (percentage >= INIT_PERCENTAGE) { 
      mPlayer = new MediaPlayer(); 
      try { 
       mPlayer.setDataSource(mDownloader.getDownloadingFile().getAbsolutePath()); 
       mPlayer.prepare(); 
       mPlayer.start(); 

       mHandler.postDelayed(prepareSecondaryPlayerRunnable, mPlayer.getDuration() - PREPARE_NEXT_PLAYER_OFFSET); 
       mHandler.postDelayed(startNextPlayerRunnable, mPlayer.getDuration() - START_NEXT_OFFSET); 

      } catch (IOException e) { 
       Log.e(e); 
      } 

      mDownloader.setDownloadListener(null); 
     } 
    } 
}; 

// Starting to prepare secondary MediaPlayer 
private Runnable prepareSecondaryPlayerRunnable = new Runnable() { 
    public void run() { 
     mSecondaryPlayer = new MediaPlayer(); 
     try { 
      mSecondaryPlayer.setDataSource(mDownloader.getDownloadingFile().getAbsolutePath()); 
      mSecondaryPlayer.prepare(); 
      mSecondaryPlayer.seekTo(mPlayer.getDuration() - START_NEXT_OFFSET); 

     } catch (IOException e) { 
      Log.e(e); 
     } 
    } 
}; 

// Starting secondary MediaPlayer playback, scheduling creating next MediaPlayer 
private Runnable startNextPlayerRunnable = new Runnable() { 
    public void run() { 
     mSecondaryPlayer.start(); 

     mHandler.postDelayed(prepareSecondaryPlayerRunnable, mSecondaryPlayer.getDuration() - mPlayer.getCurrentPosition() - PREPARE_NEXT_PLAYER_OFFSET); 
     mHandler.postDelayed(startNextPlayerRunnable, mSecondaryPlayer.getDuration() - mPlayer.getCurrentPosition() - START_NEXT_OFFSET); 

     mPlayer.pause(); 
     mPlayer.release(); 

     mPlayer = mSecondaryPlayer; 

    } 
}; 

फिर से - लगता है, एक योजना की तरह है, लेकिन पूरी तरह से नहीं काम करता है। MediaPlayers स्विच करने के क्षण काफी सुनहरे हैं। यहां मेरे विपरीत स्थिति है: 4.1 टैबलेट पर यह ठीक है, लेकिन एचटीसी सेंसेशन पर स्पष्ट अंतराल हैं।

मैंने विभिन्न डाउनलोड तकनीकों को लागू करने का भी प्रयास किया। मैंने 10 केबी भाग और एमपी 3 फ्रेम द्वारा डाउनलोड लागू किया है। मुझे बिल्कुल पता नहीं है, लेकिन ऐसा लगता है कि एमपी 3 फ्रेम के मामले में और बेहतर काम शुरू करने के लिए। लेकिन यह सिर्फ एक भावना है, मुझे स्पष्टीकरण नहीं पता है।

StreamingMediaPlayer

मैं इस शब्द को कई बार देखा था, जबकि googling, और इस कार्यान्वयन पाया: https://code.google.com/p/mynpr/source/browse/trunk/mynpr/src/com/webeclubbin/mynpr/StreamingMediaPlayer.java?r=18

यह एक समाधान हर कोई का उपयोग किया जाता है?

यदि हां, तो यह दुखद है, क्योंकि यह मेरे लिए भी अच्छा काम नहीं कर रहा है। और मुझे कार्यान्वयन में कोई नया विचार नहीं दिख रहा है।

तो, सवाल

कैसे तुम लोग अपने ऐप्लिकेशन में ऑडियो स्ट्रीमिंग लागू करते हैं? मैं निराश नहीं हूं मैं अकेला व्यक्ति हूं जिसने इस तरह की समस्याओं का सामना किया। कुछ अच्छे प्रथाएं होनी चाहिए।

+0

बहुत अच्छा सवाल ... यह मुझे पिछले 2 सप्ताह से भी परेशान कर रहा है ... लेकिन मुझे इसे एक स्ट्रीमिंग से वीडियो स्ट्रीमिंग के लिए चाहिए ... ऑडियो स्ट्रीमिंग के लिए –

+0

आपको एंड्रॉइड सेवाओं के साथ अपने स्वयं के कस्टम प्लेयर का उपयोग करना चाहिए –

+0

महान सवाल ... दुर्भाग्य से एंड्रॉइड का मीडियाप्लेयर कभी भी लिखे गए सॉफ़्टवेयर के सबसे खराब टुकड़ों में से एक है। – StackOverflowed

उत्तर

1

मेरे मामले में मैं ओपनएसएल ईएस के साथ एफएफएमपीईजी का उपयोग करता हूं। नुकसान जटिलता है। आपको बहुत सी चीजों से परिचित होना चाहिए: जेएनआई, ओपनएसएल, एफएफएमपीईजी। डीबग करना भी मुश्किल है (शुद्ध जावा एंड्रॉइड ऐप की तुलना में)। आपके मामले में मैं आपको कम स्तर Media API आज़माने का सुझाव देता हूं। केवल एक चीज उदाहरणों की कमी है। लेकिन unit test है जो दिखाता है कि आप ऑडियो कैसे संभाल सकते हैं (आपको InputStream संदर्भ-रेखा 82 को बदलने की आवश्यकता है)।

+1

मैंने एफएफएमपीईजी के बारे में सोचा, लेकिन यह आखिरी चीज होगी जो मैं कोशिश करूंगा, क्योंकि इसका उपयोग करना बहुत मुश्किल है। मीडिया एपीआई पर मुझे इंगित करने के लिए धन्यवाद, मैं इसे आजमाउंगा। – darja

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