基于开源库NanoHttpd开发
1·支持本地视频文件(mov/mp4)发送
2·支持浏览器播放
3·支持ffplay/VLC播放
4·支持拖动播放
自定义服务器:
@Override
public Response serve(IHTTPSession session) {
String range = null;
Map<String, String> headers = session.getHeaders();
// Jlog.e(tag, "Request headers:");
for (String key : headers.keySet()) {
Log.i(tag, " " + key + ":" + headers.get(key));
if ("range".equals(key)) {
range = headers.get(key);
}
}
// return responseVideoStream();
if (range != null) {
try {
return getPartialResponse(range);
} catch (IOException e) {
e.printStackTrace();
}
}
Log.w(tag, "Not support range");
return responseVideoStream();
}
拖动播放实现:
private Response getPartialResponse(String rangeHeader) throws IOException {
String rangeValue = rangeHeader.trim().substring("bytes=".length());
String path = Environment.getExternalStorageDirectory().getPath() + "/dst.mov";
File file = new File(path);
if (!file.exists()) {
Log.e(tag, "File not exit!");
return null;
}
if (mFileInputStream != null) {
mFileInputStream.close();
}
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;
mFileInputStream = new FileInputStream(file);
if (start != 0) mFileInputStream.skip(start);
Response response = newFixedLengthResponse(Response.Status.PARTIAL_CONTENT, "video/mp4", mFileInputStream, contentLength);
response.addHeader("Content-Length", contentLength + "");
response.addHeader("Content-Range", "bytes " + start + "-" + end + "/" + fileLength);
response.addHeader("Content-Type", "video/mp4");
return response;
} else {
Log.e(tag, "start=" + start + " > end=" + end);
return newFixedLengthResponse(Response.Status.BAD_REQUEST, NanoHTTPD.MIME_PLAINTEXT, "Has closed");
}
}