2012-02-29 19 views
11

नैनो एचटीपीडी सर्वर कोड here पाया जा सकता है।NanoHttpd सर्वर एंड्रॉइड पर बड़े वीडियो स्ट्रीम नहीं कर सकता

मैं एक ऐसी सेवा में एक नया थ्रेड शुरू कर रहा हूं जो बड़े वीडियो (लगभग 150 एमबी) स्ट्रीम करने के लिए नैनो एचटीपीडी सर्वर का उपयोग करता है लेकिन लोडिंग संवाद दिखाए जाने पर यह सही हो जाता है। मैंने बफर को बढ़ाने और घटाने की कोशिश की, इसका कोई फायदा नहीं हुआ। ऐसा लगता है कि सर्वर एक एंड्रॉइड डिवाइस पर ठीक से नहीं चल सकता है।

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

उत्तर

2

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

+0

क्या आप अपना कोड साझा करना चाहते हैं? मैं एक ऐप बनाने की तलाश में हूं जो इनपुट इनपुट से वीडियो स्ट्रीम करता है, और मुझे यह देखना अच्छा लगेगा कि मैं आपके कोड से कोई पॉइंटर्स प्राप्त कर सकता हूं या नहीं। मुझे आपकी मदद के लिए आपको एक उपहार देने के लिए खुशी होगी। अग्रिम में धन्यवाद! –

+0

एक इनपुटस्ट्रीम से स्ट्रीमिंग वीडियो वास्तव में समस्या पर मेरा पहला शॉट था, लेकिन जब ऐसा लगता है कि मैंने एंड्रॉइड के मीडिया प्लेयर पर इसे आजमाया था, तो यह वास्तव में इनपुट पट्टी() विधियों का उपयोग करके इनपुटस्ट्रीम का उपभोग नहीं कर रहा है, बल्कि यह केवल इनपुट स्ट्रीम को संदर्भ – josephus

+0

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

3

किसी भी चीज़ से अधिक एफवाईआई, लेकिन, नैनो एचटीपीडी का नवीनतम संस्करण (http://github.com/NanoHttpd/nanohttpd पर उपलब्ध) को कम स्मृति पदचिह्न के साथ बड़े अपलोड को बेहतर समर्थन देने के लिए अनुकूलित किया गया है। जिस कोड का आप उपयोग कर रहे हैं वह स्मृति में आने वाले अपलोड को रखता है, नया संस्करण डिस्क पर लिखता है। इसे देखें और देखें कि क्या यह स्मृति समस्याओं को हल कर सकता है।

+0

बढ़िया! सर उठाने के लिए धन्यवाद। जब मैं अपनी मेज पर वापस आऊंगा तो इसमें देखेंगे। – josephus

13

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

@Override 
@SuppressWarnings("deprecation") 
public Response serve(String uri, Method method, Map<String, String> headers, Map<String, String> params, Map<String, String> files) { 
    String mimeType = getMimeType(); 
    String currentUri = getCurrentUri(); 
    if (currentUri != null && currentUri.equals(uri)) { 
     String range = null; 
     Log.d(TAG, "Request headers:"); 
     for (String key : headers.keySet()) { 
      Log.d(TAG, " " + key + ":" + headers.get(key)); 
      if ("range".equals(key)) { 
       range = headers.get(key); 
      } 
     } 
     try { 
      if (range == null) { 
       return getFullResponse(mimeType); 
      } else { 
       return getPartialResponse(mimeType, range); 
      } 
     } catch (IOException e) { 
      Log.e(TAG, "Exception serving file: " + filePath, e); 
     } 
    } else { 
     Log.d(TAG, "Not serving request for: " + uri); 
    } 

    return new Response(Response.Status.NOT_FOUND, mimeType, "File not found"); 
} 

private Response getFullResponse(String mimeType) throws FileNotFoundException { 
    cleanupStreams(); 
    fileInputStream = new FileInputStream(filePath); 
    return new Response(Response.Status.OK, mimeType, fileInputStream); 
} 

private Response getPartialResponse(String mimeType, String rangeHeader) throws IOException { 
    File file = new File(filePath); 
    String rangeValue = rangeHeader.trim().substring("bytes=".length()); 
    long fileLength = file.length(); 
    long start, end; 
    if (rangeValue.startsWith("-")) { 
     end = fileLength - 1; 
     start = fileLength - 1 
       - Long.parseLong(rangeValue.substring("-".length())); 
    } else { 
     String[] range = rangeValue.split("-"); 
     start = Long.parseLong(range[0]); 
     end = range.length > 1 ? Long.parseLong(range[1]) 
       : fileLength - 1; 
    } 
    if (end > fileLength - 1) { 
     end = fileLength - 1; 
    } 
    if (start <= end) { 
     long contentLength = end - start + 1; 
     cleanupStreams(); 
     fileInputStream = new FileInputStream(file); 
     //noinspection ResultOfMethodCallIgnored 
     fileInputStream.skip(start); 
     Response response = new Response(Response.Status.PARTIAL_CONTENT, mimeType, fileInputStream); 
     response.addHeader("Content-Length", contentLength + ""); 
     response.addHeader("Content-Range", "bytes " + start + "-" + end + "/" + fileLength); 
     response.addHeader("Content-Type", mimeType); 
     return response; 
    } else { 
     return new Response(Response.Status.RANGE_NOT_SATISFIABLE, HTML_MIME_TYPE, rangeHeader); 
    } 
} 
+2

क्या आप इस उत्तर को पूर्ण सर्वर कार्यान्वयन के साथ अपडेट कर सकते हैं? –

+0

वाह, यह सही कोड है! यह वीडियो व्यू का उपयोग करते समय अपेक्षित काम कर रहा है, लेकिन मैं MediaExtractor का उपयोग करके वीडियो खेलना चाहता था। क्या आप क्लाइंट साइड कोड के साथ मेरी मदद कर सकते हैं? – Boobalan

4

यह, के कारण HTTP हेडर आरंभ नहीं एक मुद्दा है, इसलिए यदि उपयोगकर्ता कॉल सबसे पहले दूसरी रेंज अनुरोध के साथ मिलता है, तो सीमा क्षेत्र के बिना किसी अन्य GET अनुरोध कहते हैं, पिछले सीमा क्षेत्र अभी भी वहाँ रखेंगे, लेकिन वास्तव में अनुरोध प्राप्त करें इसे सीमा से पढ़ने की उम्मीद नहीं है।

एंड्रॉइड मीडियाप्लेयर अंत में एमओवी बॉक्स के साथ एमपी 4 फ़ाइल के लिए ऐसा मामला है, जो वास्तव में इच्छित डेटा को पढ़ने का कारण बनता है। यह सुधार के साथ

diff --git a/core/src/main/java/fi/iki/elonen/NanoHTTPD.java b/core/src/main/java/fi/iki/elonen/NanoHTTPD.java 
index ce292a4..aba21c4 100644 
--- a/core/src/main/java/fi/iki/elonen/NanoHTTPD.java 
+++ b/core/src/main/java/fi/iki/elonen/NanoHTTPD.java 
@@ -1039,6 +1039,7 @@ public abstract class NanoHTTPD { 
      */ 
     private void decodeHeader(BufferedReader in, Map<String, String> pre, Map<String, String> parms, Map<String, St 
      throws ResponseException { 
+   headers.put("range","bytes=0-"); 
      try { 
       // Read the request line 
       String inLine = in.readLine(); 

, यह एंड्रॉयड 5.0 डिवाइस पर मेरे लिए ठीक काम करता है:

इस समस्या को हल करने के लिए आप पैच नीचे की कोशिश कर सकते हैं।

+0

यह बहुत अच्छा जवाब है। मैंने वीडियो स्ट्रीम करने के लिए नैनो एचटीटीपीडी का इस्तेमाल किया, यह कई फोनों में ठीक काम करता है, लेकिन सैमसंग एस 4 के लिए काम नहीं करता है। इस फिक्स ने मेरी मदद की, धन्यवाद – thomasdao

+0

इसके लिए धन्यवाद, बहुत मदद की। –

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

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