2013-10-14 5 views
14

का उपयोग कर एसडीकार्ड पर फ़ाइल कैसे सेवा करें मैंने नैनो एचटीटीपीडी का उपयोग करके एक छोटा एंड्रॉइड सर्वर लिखा है। यह एक HTML फ़ाइल अच्छी तरह से सेवा कर सकता है (वेब ​​पेज एसडीकार्ड/www/index.html पर स्थित है)। क्या कोई मुझे यह जानने में मदद कर सकता है कि मैं नैनो एचटीटीपीडी का उपयोग कर एचटीएमएल पेज की बजाय ऑडियो या वीडियो फाइल कैसे सेवा कर सकता हूं? अगर मुझे मूर्खतापूर्ण लगता है, तो मुझे माफ़ कर दो, क्योंकि मैं HTTP में नया हूं! यहाँ मेरी सर्वर साइड कोड है (मैं एक ऑडियो फ़ाइल की है कि वेबपेज पथ बदल दिया है):NanoHTTPD (एंड्रॉइड के अंदर)

<uses-permission android:name="android.permission.INTERNET"/> 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 

कोई मदद:

package com.example.zserver; 

import java.io.BufferedReader; 
import java.io.File; 
import java.io.FileReader; 
import java.io.IOException; 
import java.util.Map; 

import android.app.Activity; 
import android.os.Bundle; 
import android.os.Environment; 
import android.util.Log; 

public class MainActivity extends Activity { 

    private WebServer server; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     server = new WebServer(); 
     try { 
      server.start(); 
     } catch(IOException ioe) { 
      Log.w("Httpd", "The server could not start."); 
     } 
     Log.w("Httpd", "Web server initialized."); 

    } 
    @Override 
    public void onDestroy() 
    { 
     super.onDestroy(); 
     if (server != null) 
      server.stop(); 
    } 

    private class WebServer extends NanoHTTPD { 

     public WebServer() 
     { 
      super(8080); 
     } 

     @Override 
     public Response serve(String uri, Method method, 
           Map<String, String> header, 
           Map<String, String> parameters, 
           Map<String, String> files) { 
      String answer = ""; 
      try { 
       // Opening file from SD Card 
       File root = Environment.getExternalStorageDirectory(); 
       FileReader index = new FileReader(root.getAbsolutePath() + 
         "/www/music.mp3");    
       BufferedReader reader = new BufferedReader(index); 
       String line = ""; 
       while ((line = reader.readLine()) != null) { 
        answer += line; 
       } 

      } catch(IOException ioe) { 
       Log.w("Httpd", ioe.toString()); 
      } 


      return new NanoHTTPD.Response(answer); 
     } 
    } 

} 

मैं अपने कोड में आवश्यक उपयोग-अनुमतियों को शामिल किया है सराहनीय होगा। अग्रिम में धन्यवाद!

संपादित करें, जोड़ा अनुमति:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> 

EDIT1: पढ़ने की विहित रास्ता और बफ़र्स के लिए लिख:

int read; 
     int n=1; 
     while((read = dis.read(mybytearray)) != -1){ 
      dos.write(mybytearray, 0, read);} 

उत्तर

35

सबसे पहले, आपको यह सुनिश्चित करना होगा कि आप मीडिया फ़ाइलों की सेवा करते समय mimetype को सही तरीके से सेट करें।

दूसरा, आप FileReader का उपयोग करके लाइन द्वारा एमपी 3 फ़ाइल लाइन को बहुत दूर नहीं पढ़ पाएंगे, इसके बजाय आपको InputStream के साथ नैनो एचटीटीपीडी प्रदान करना चाहिए।

नीचे आपके कोड का एक कामकाजी संशोधित संस्करण है, जो एक एमपी 3 फ़ाइल परोसता है। Mimetype को audio/mpeg पर सेट करके आप ब्राउज़र को यह तय करने दें कि इस सामग्री के साथ क्या करना है। क्रोम में, उदाहरण के लिए, एकीकृत संगीत प्लेयर लॉन्च और फ़ाइल चलाता है।

public class StackOverflowMp3Server extends NanoHTTPD { 

    public StackOverflowMp3Server() { 
     super(8089); 
    } 

    @Override 
    public Response serve(String uri, Method method, 
     Map<String, String> header, Map<String, String> parameters, 
     Map<String, String> files) { 
    String answer = ""; 

    FileInputStream fis = null; 
    try { 
     fis = new FileInputStream(Environment.getExternalStorageDirectory() 
       + "/music/musicfile.mp3"); 
    } catch (FileNotFoundException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    return new NanoHTTPD.Response(Status.OK, "audio/mpeg", fis); 
    } 
} 

संपादित करें: बहुत से लोगों को अवधियों का उपयोग करते हुए seekable ऑडियो फाइल बनाने के लिए कैसे पूछ कर दिया गया है, मैं इस

नीचे ऑडियो फ़ाइल seekable बनाने के प्रदर्शित होगा, अवधियों का उपयोग किया जाता है जो HTTP क्लाइंट को ऑडियो फाइलों के हिस्सों को हिस्सों में पुनर्प्राप्त करने में सक्षम बनाता है। सुनिश्चित करें कि आप PARTIAL_CONTENT प्रतिक्रिया स्थिति (HTTP 206) के साथ फ़ाइल की सेवा कर रहे हैं। एक उदाहरण कार्यान्वयन नैनो एचटीटीपीडी के उदाहरण कोड में पाया जा सकता है: SimpleWebserver.java

मेरे कार्यान्वयन में, सीधे सेवा पद्धति में एक नैनो एचटीटीपीडी प्रतिक्रिया लौटने की बजाय, मैं "सर्विसफाइल" नामक एक और विधि बनाता हूं जिसका उपयोग मैं हैंडलिंग के लिए प्रतिक्रिया के रूप में करता हूं सीमा अनुरोध, जैसा कि आप नीचे देख सकते हैं। यह कोड ऊपर से जुड़े SimpleWebServer.java का एक संशोधित कार्यान्वयन है।

@Override 
    public Response serve(String uri, Method method, 
     Map<String, String> header, Map<String, String> parameters, 
     Map<String, String> files) { 

    File f = new File(Environment.getExternalStorageDirectory() 
      + "/music/musicfile.mp3");  
    String mimeType = "audio/mpeg"; 

    return serveFile(uri, header, f, mimeType); 
} 
//Announce that the file server accepts partial content requests 
private Response createResponse(Response.Status status, String mimeType, 
     InputStream message) { 
    Response res = new Response(status, mimeType, message); 
    res.addHeader("Accept-Ranges", "bytes"); 
    return res; 
} 

/** 
* Serves file from homeDir and its' subdirectories (only). Uses only URI, 
* ignores all headers and HTTP parameters. 
*/ 
private Response serveFile(String uri, Map<String, String> header, 
     File file, String mime) { 
    Response res; 
    try { 
     // Calculate etag 
     String etag = Integer.toHexString((file.getAbsolutePath() 
       + file.lastModified() + "" + file.length()).hashCode()); 

     // Support (simple) skipping: 
     long startFrom = 0; 
     long endAt = -1; 
     String range = header.get("range"); 
     if (range != null) { 
      if (range.startsWith("bytes=")) { 
       range = range.substring("bytes=".length()); 
       int minus = range.indexOf('-'); 
       try { 
        if (minus > 0) { 
         startFrom = Long.parseLong(range 
           .substring(0, minus)); 
         endAt = Long.parseLong(range.substring(minus + 1)); 
        } 
       } catch (NumberFormatException ignored) { 
       } 
      } 
     } 

     // Change return code and add Content-Range header when skipping is 
     // requested 
     long fileLen = file.length(); 
     if (range != null && startFrom >= 0) { 
      if (startFrom >= fileLen) { 
       res = createResponse(Response.Status.RANGE_NOT_SATISFIABLE, 
         NanoHTTPD.MIME_PLAINTEXT, ""); 
       res.addHeader("Content-Range", "bytes 0-0/" + fileLen); 
       res.addHeader("ETag", etag); 
      } else { 
       if (endAt < 0) { 
        endAt = fileLen - 1; 
       } 
       long newLen = endAt - startFrom + 1; 
       if (newLen < 0) { 
        newLen = 0; 
       } 

       final long dataLen = newLen; 
       FileInputStream fis = new FileInputStream(file) { 
        @Override 
        public int available() throws IOException { 
         return (int) dataLen; 
        } 
       }; 
       fis.skip(startFrom); 

       res = createResponse(Response.Status.PARTIAL_CONTENT, mime, 
         fis); 
       res.addHeader("Content-Length", "" + dataLen); 
       res.addHeader("Content-Range", "bytes " + startFrom + "-" 
         + endAt + "/" + fileLen); 
       res.addHeader("ETag", etag); 
      } 
     } else { 
      if (etag.equals(header.get("if-none-match"))) 
       res = createResponse(Response.Status.NOT_MODIFIED, mime, ""); 
      else { 
       res = createResponse(Response.Status.OK, mime, 
         new FileInputStream(file)); 
       res.addHeader("Content-Length", "" + fileLen); 
       res.addHeader("ETag", etag); 
      } 
     } 
    } catch (IOException ioe) { 
     res = createResponse(Response.Status.FORBIDDEN, 
       NanoHTTPD.MIME_PLAINTEXT, "FORBIDDEN: Reading file failed."); 
    } 

    return res; 
} 
+0

बहुत बहुत धन्यवाद! यह छोटे मीडिया के लिए ठीक काम करता है। मैं सोच रहा था कि पढ़ने/लिखने (बफर का उपयोग करके) के कैनोलिक तरीके को कैसे शामिल किया जाए ताकि बड़ी फ़ाइलों को स्थानांतरित किया जा सके। कस्टम प्रोटोकॉल में, यह सीधे आगे है। मैं बस एक बफर (डेटा इनपुट स्ट्रीम से भरा) से पढ़ता हूं और साथ ही इसे डेटा आउटपुट स्ट्रीम में लिखता हूं। मुझे यकीन नहीं है कि यह HTTP में कैसे प्राप्त किया जा सकता है। मैं प्रत्येक डेटा खंड में हेडर जोड़ने के बिना लगातार डेटा नहीं भेज सकता .. या शायद मुझे कुछ याद आ रहा है। क्या आप नमूना कोड प्रदान कर सकते हैं? विवरण के लिए कृपया मेरे संपादन खंड का संदर्भ लें। एक बार फिर धन्यवाद। –

+0

स्थिति।ठीक है एमपी 3 एचटीएमएल 5 प्लेयर में तलाशने की इजाजत नहीं दे रहा है, कृपया मुझे बताएं कि मुझे प्लेयर – yourkishore

+0

में इसे बनाने के लिए उपयोगकर्ता को क्या हेडर चाहिए, मैंने अपने फोन से अपने फोन से एमपी 3 स्ट्रीम करने के लिए इस कोड का इस्तेमाल किया। मुझे त्रुटि मिल रही है '403 निषिद्ध (/) '। इसे कैसे ठीक करें? –

0

आप भी जोड़ने की अनुमति android.permission.READ_EXTERNAL_STORAGE

की आवश्यकता नहीं है

क्योंकि आप एक फ़ाइल पढ़ रहे हैं।

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