2016-01-22 3 views
5

Мне нужно потоковое видео и воспроизведение на веб-странице. Я использую библиотеку Nanohttpd для запуска сервера в своем приложении для Android. Я могу передавать и воспроизводить видео при загрузке страницы. После завершения воспроизведения видео я не могу воспроизвести видео во второй раз. Каждый раз, когда мне нужно обновить страницу, чтобы воспроизвести видео. При попытке воспроизведения во второй раз я получаю следующую ошибку.Потоковое видео с использованием NanoHttpd, Ошибка: java.net.SocketException: sendto failed: EPIPE (Broken pipe)

java.net.SocketException: sendto failed: EPIPE (Broken pipe) 
    at libcore.io.IoBridge.maybeThrowAfterSendto(IoBridge.java:546) 
    at libcore.io.IoBridge.sendto(IoBridge.java:515) 
    at java.net.PlainSocketImpl.write(PlainSocketImpl.java:504) 
    at java.net.PlainSocketImpl.access$100(PlainSocketImpl.java:37) 
    at java.net.PlainSocketImpl$PlainSocketOutputStream.write(PlainSocketImpl.java:266) 
    at server.http.android.androidhttpserver.server.NanoHTTPD$Response.sendBody(NanoHTTPD.java:1386) 
    at server.http.android.androidhttpserver.server.NanoHTTPD$Response.sendBodyWithCorrectEncoding(NanoHTTPD.java:1359) 
    at server.http.android.androidhttpserver.server.NanoHTTPD$Response.sendBodyWithCorrectTransferAndEncoding(NanoHTTPD.java:1349) 
    at server.http.android.androidhttpserver.server.NanoHTTPD$Response.send(NanoHTTPD.java:1335) 
    at server.http.android.androidhttpserver.server.NanoHTTPD$HTTPSession.execute(NanoHTTPD.java:769) 
    at server.http.android.androidhttpserver.server.NanoHTTPD$ClientHandler.run(NanoHTTPD.java:186) 
    at java.lang.Thread.run(Thread.java:818) 
Caused by: android.system.ErrnoException: sendto failed: EPIPE (Broken pipe) 
    at libcore.io.Posix.sendtoBytes(Native Method) 
    at libcore.io.Posix.sendto(Posix.java:176) 
    at libcore.io.BlockGuardOs.sendto(BlockGuardOs.java:278) 
    at libcore.io.IoBridge.sendto(IoBridge.java:513) 
    at java.net.PlainSocketImpl.write(PlainSocketImpl.java:504) 
    at java.net.PlainSocketImpl.access$100(PlainSocketImpl.java:37) 
    at java.net.PlainSocketImpl$PlainSocketOutputStream.write(PlainSocketImpl.java:266) 
    at server.http.android.androidhttpserver.server.NanoHTTPD$Response.sendBody(NanoHTTPD.java:1386) 
    at server.http.android.androidhttpserver.server.NanoHTTPD$Response.sendBodyWithCorrectEncoding(NanoHTTPD.java:1359) 
    at server.http.android.androidhttpserver.server.NanoHTTPD$Response.sendBodyWithCorrectTransferAndEncoding(NanoHTTPD.java:1349) 
    at server.http.android.androidhttpserver.server.NanoHTTPD$Response.send(NanoHTTPD.java:1335) 
    at server.http.android.androidhttpserver.server.NanoHTTPD$HTTPSession.execute(NanoHTTPD.java:769) 
    at server.http.android.androidhttpserver.server.NanoHTTPD$ClientHandler.run(NanoHTTPD.java:186) 
    at java.lang.Thread.run(Thread.java:818) 

Я посылаю ответ следующим образом.

@Override 
public Response serve(IHTTPSession session) { 
    FileInputStream fis = null; 
    File file = new File("/storage/emulated/0/DCIM/Camera/VIDEO.mp4"); 
    try{ 
     if(file.exists()) 
     { 
      fis = new FileInputStream(file); 
     } 
     else 
     Log.d("FOF :", "File Not exists:"); 
    }catch (FileNotFoundException e) 
    { 
     e.printStackTrace(); 
    } 
    return new NanoHTTPD.Response(Response.Status.OK,"video/mp4",fis, file.length()); 
} 

HTML-файл, чтобы получить доступ к видео является

<html><body> 
<video id="video_id" width="420" autoplay loop> 
    <source src=http://192.168.2.6:8080/ type="video/mp4"> 
    </video> 
</body></html> 

Просьба предоставить мне решение для воспроизведения видео непрерывно без обновления веб-страницы.

ответ

3

Я успешно со следующими кодами:

@Override 
public Response serve(IHTTPSession session) { 
    Map<String, String> headers = session.getHeaders(); 
    Map<String, String> parms = session.getParms(); 
    Method method = session.getMethod(); 
    String uri = session.getUri(); 
    Map<String, String> files = new HashMap<>(); 

    if (Method.POST.equals(method) || Method.PUT.equals(method)) { 
     try { 
      session.parseBody(files); 
     } 
     catch (IOException e) { 
      return getResponse("Internal Error IO Exception: " + e.getMessage()); 
     } 
     catch (ResponseException e) { 
      return new Response(e.getStatus(), MIME_PLAINTEXT, e.getMessage()); 
     } 
    } 

    uri = uri.trim().replace(File.separatorChar, '/'); 
    if (uri.indexOf('?') >= 0) { 
     uri = uri.substring(0, uri.indexOf('?')); 
    } 

    File f = new File(uri); 
    return serveFile(uri, header, f); 
} 

private Response serveFile(String uri, Map<String, String> header, File file) { 
    Response res; 
    String mime = getMimeTypeForFile(uri); 
    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, 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 = getResponse("Forbidden: Reading file failed"); 
    } 

    return (res == null) ? getResponse("Error 404: File not found") : res; 
} 

// 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; 
} 

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

private Response getResponse(String message) { 
    return createResponse(Response.Status.OK, "text/plain", message); 
} 
+0

Что GetResponse() метод определяет? –

+0

private Response getResponse (String message) { return createResponse (Response.Status.OK, "text/plain", message); } – ZulNs

+0

Я получаю следующее предупреждение в NanoHTTPD.java 'serve (java.lang.String, server.http.android.androidhttpserver.server.NanoHTTPD.Method, java.util.Map , java.util.Map , java.util.Map ) 'устарел Эта инспекция сообщает, что в указанном объеме проверки используется устаревший код. –