NanoHttpd-Server kann keine großen Videos auf Android übertragen

NanoHttpd Server Code finden Sie hier .

Ich beginne einen neuen Thread in einem Dienst, der NanoHttpd-Server verwendet, um große Videos zu streamen (ca. 150mb), aber es pausiert gerade rechts, während der Lade-Dialog angezeigt wird. Ich habe versucht zu erhöhen und die Puffer lautet ohne Erfolg. Es scheint, dass der Server nicht ordnungsgemäß auf einem Android-Gerät laufen kann.

Der gleiche Code funktioniert gut, wenn ich den Server über Desktop-Anwendung starten. Ich kann mehr als 150mb strömen Beim Ausführen des Servers vom Telefon habe ich nur 20mb Dateien probiert und sie waren auch gut. Allerdings muss ich viel mehr streamen als das.

  • Konvertieren Sie Video Input Stream zu RTMP
  • Live-Streaming mit Android-Gerät
  • Android-Video-Streaming-Beispiel
  • Android MediaPlayer persistenten Cache mit ExoPlayer
  • Android: Streaming die Kamera als mjpeg
  • Gibt es eine Möglichkeit, VideoView im Hintergrund auf Android App zu spielen?
  • MediaRecorder Ausgabe auf Android Lollipop
  • Weird Verhalten beim Streaming mit Android MediaPlayer auf HTC Desire mit Android 2.2
  • 4 Solutions collect form web for “NanoHttpd-Server kann keine großen Videos auf Android übertragen”

    Falls andere dazu kommen und sehen wollen, was der eigentliche Code in dieser Lösung ist, schreibe ich hier meinen Code. Ich benutze mein Android-Gerät, um eine Videodatei von der SD-Karte für eine Chromecast-Anfrage zu streamen. Mit diesem Code bin ich in der Lage, den Stream in der Mitte zu starten und / oder suche zu einem bestimmten Ort im Stream.

    @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); } } 

    Dies ist ein Problem aufgrund der HTTP-Header nicht initialisiert, so dass, wenn Benutzer anrufen GET mit Bereichsanforderung zuerst, dann rufen Sie eine andere GET-Anfrage ohne Bereich Feld, das vorherige Bereich Feld wird immer noch dort, aber eigentlich die zweite GET-Anfrage nicht erwartet werden Lese es aus dem Bereich.

    Android MediaPlayer ist so Fall für mp4-Datei mit Moov-Box am Ende, die dazu führen, lesen Daten tatsächlich nicht wir wollen.

    Um dieses Problem zu beheben, können Sie unten Patch ausführen:

     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(); 

    Mit diesem Fix, funktioniert es gut für mich auf Android 5.0 Gerät.

    Mehr von einem FYI als alles andere, aber die neueste Version von NanoHttpd (erhältlich unter http://github.com/NanoHttpd/nanohttpd ) wurde optimiert, um große Uploads mit einem reduzierten Speicherplatz zu unterstützen. Der Code, den Sie verwenden, hält den eingehenden Upload im Speicher, die neuere Version schreibt auf Festplatte. Überprüfen Sie es heraus und sehen Sie, ob es Speicherprobleme lösen könnte.

    Löste mein eigenes Problem. Das Problem ist, dass die MediaPlayer (s) (wmp, vlc, android player), eine GET-Anfrage mit einem bestimmten RANGE ausgeben. Serviert diese Anfrage richtig, Problem gelöst.

    Das Android ist ein Google Android Fan-Website, Alles ├╝ber Android Phones, Android Wear, Android Dev und Android Spiele Apps und so weiter.