Android NanoHTTPD Постоянное подключение к потоковому контенту

Я использовал NanoHTTPD в одном из наших приложений для передачи контента, включая аудио и видео, с локальной карты SDCard в Webview. Заголовки диапазона и длины контента, а также статус HTTP настроены правильно. Теперь у нас есть вариант использования, когда мы хотим обслуживать контент на сервере через NanoHTTPD.

Проблема с подходом NanoHTTPD заключается в том, что он считывает весь контент, который запрашивает Webview. В случае с локальным файлом все еще в порядке, но вы не можете ждать, пока он получит столько контента с сервера и сбросит поток вывода.

Я ищу подход, при котором я могу открыть соединение и продолжать обслуживать часть запрошенных данных. Так же, как это работает при получении контента с заголовками диапазона в запросе. Соединение остается открытым, и видеопроигрыватель начинает воспроизводиться, как только у него достаточно буфера.

Пожалуйста помоги.


person Pulkit Gupta    schedule 24.10.2015    source источник


Ответы (1)


Я решил это с помощью HTTP-клиента. Я зарегистрировал шаблон на локальном хосте с уникальным портом и обработал ответ для больших носителей, добавив соответствующие заголовки, статус и длину контента. Здесь нужно сделать три вещи:

1) Скопируйте заголовки из ответа HTTP в локальный ответ
2) Установите код ответа. Полное содержимое (200) или частичное содержимое (206)
3) Создайте новый объект InputStreamEntity и добавьте его в ответ.

@Override
    public void handle(HttpRequest request, HttpResponse response, HttpContext context) throws HttpException, IOException {
        String range = null;
        //Check if there's range in request header 
        Header rangeHeader = request.getFirstHeader("range");

        if (rangeHeader != null) {
            range = rangeHeader.getValue();
        }

        URL url = new URL(mediaURL);
        URLConnection urlConn = url.openConnection();

        if (!(urlConn instanceof HttpURLConnection)) {
            throw new IOException("URL is not an Http URL");
        }
        HttpURLConnection httpConn = (HttpURLConnection) urlConn;
        httpConn.setRequestMethod("GET");

        //If range is present, direct HTTPConnection to fetch data for that range only    
        if(range!=null){
            httpConn.setRequestProperty("Range",range);
        }
        //Add any custom header to request that you want and then connect.
        httpConn.connect();

        int statusCode = httpConn.getResponseCode();

        //Copy all headers with valid key to response. Exclude content-length as that's something response gets from the entity. 
        Map<String, List<String>> headersMap =  httpConn.getHeaderFields();
        for (Map.Entry<String, List<String>> entry : headersMap.entrySet())
        {
            if(entry.getKey() != null && !entry.getKey().equalsIgnoreCase("content-length")) {
                for (int i = 0; i < entry.getValue().size(); i++) {
                    response.setHeader(entry.getKey(), entry.getValue().get(i));
                }
            }
        }

        //Important to set correct status code
        response.setStatusCode(statusCode);

        //Pass the InputStream to response and that's it.
        InputStreamEntity entity = new InputStreamEntity(httpConn.getInputStream(), httpConn.getContentLength());
        entity.setContentType(httpConn.getContentType());
        response.setEntity(entity);

    }
person Pulkit Gupta    schedule 27.10.2015