W przypadku, gdy inni natkną się na to i chcą zobaczyć, jaki jest aktualny kod w tym rozwiązaniu, zamieszczam tutaj mój kod. Używam urządzenia z Androidem do strumieniowego przesyłania pliku wideo z karty SD na żądanie Chromecasta. Korzystając z tego kodu, jestem w stanie uruchomić strumień w środku i/lub szukać konkretnej lokalizacji w strumieniu.
@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);
}
}
Czy mógłbyś podzielić się swoim kodem? Chcę utworzyć aplikację, która przesyła strumieniowo wideo z InputStream, i chciałbym zobaczyć, czy mogę uzyskać jakieś wskazówki ze swojego kodu. Z przyjemnością nagrodzę cię nagrodą za twoją pomoc. Z góry dziękuję! –
Strumieniowanie wideo z InputStream było moim pierwszym ujęciem problemu, ale wygląda na to, gdy próbowałem go na odtwarzaczu multimedialnym Androida, tak naprawdę nie zużywa InputStream przy użyciu swoich metod read(), zamiast tego używa tylko InputStream jako odniesienia – josephus
W rzeczywistości możesz użyć kodu serwera NanoHttpd z linku w moim pytaniu i powinien on działać wystarczająco dobrze, aby przesyłać strumieniowo filmy wideo z większości odtwarzaczy. Moja sprawa była jednak specyficzna, tak że musiałem przeprowadzić manipulację bajtową przed zapisaniem danych do klienta. – josephus