0

I'm developing a Hikvision IP camera manager with SpringBoot 3.1 and Java 17. The IP cameras are linked to a server (Gateway Server as they call it) that serves a REST API. In essence I have to implement a reduced number of features like live view, list the recorded files for a camera, record on demand, alarm managing and downloading files. The last is what's giving me a lot of problems since I'm totally new in the world of cameras and streaming.

That's what I do: from the frontend the user sees a list of files that contains the past recordings of the camera. Clicking a button should give the user the selected file for download. The problem is that when the button is clicked, the response is taking a lot of time and never ends. The content-type of the response is application/binary. The request to the Gateway server is done by sending a json structure that contains a RSTP URI. Something like this:

POST:http://192.168.1.155:80/ISAPI/ContentMgmt/download?format=json&devIndex=59CAC59D-F16C-904F-A12D-3571FFA0F895

BODY:
{"downloadRequest":{"playbackURI": "rtsp://192.168.1.155:554/dac/playback/camera/59CAC59D-F16C-904F-A12D-3571FFA0F8951/MAIN/TCP?starttime=20230612T191716Z&endtime=20230612T225958Z&name=ch01_08000000011000000&size=132091216&streamform=rtp"}}

The request sending is OK, no errors given. In the documentation the only thing it says about the response is "Video file data".

Here is the method for sending the request and getting the response:


    public byte[] executeGatewayRequestForBytes(String uri, String json, DigestScheme digest){
        log.info("executing request to gateway: "+uri);
        final HttpHost target = new HttpHost("http", environment.getProperty("gateway.ip"), 80);
        HttpPost httpPost = new HttpPost(uri);
        httpPost.setEntity(new StringEntity(json, ContentType.APPLICATION_JSON));
        httpPost.setHeader("Accept", "application/json");

        AuthCache authCache = new BasicAuthCache();
        authCache.put(target,digest);

        final HttpClientContext localContext = HttpClientContext.create();
        localContext.setAttribute(HttpClientContext.AUTH_CACHE, authCache);


        try(CloseableHttpClient client = HttpClients.createDefault();

            CloseableHttpResponse response = client.execute(target,httpPost,localContext)) {

            Header[] headers = response.getHeaders();
            for (Header header : headers) {
                log.info("Key : " + header.getName()
                        + " ,Value : " + header.getValue());
            }
            HttpEntity entity = response.getEntity();

            if(entity != null){
                if(response.getCode() >= 200 && response.getCode() < 400){
                    log.info("retrieve bytes: "+ response.getHeader("Content-Length"));
                    //return EntityUtils.toByteArray(entity);
                    try (InputStream input = new ByteArrayInputStream(EntityUtils.toByteArray(entity));
                        ByteArrayOutputStream out = new ByteArrayOutputStream()) {
                        IOUtils.copy(input,out);
                        log.info("executeGatewayRequestForBytes, done with copy "+out.size());
                        return out.toByteArray();
                    }

                } else {
                    log.info("ERROR: "+response.toString());
                }
            }
        } catch (IOException | ProtocolException e) {
            throw new RuntimeException(e);
        }
        return null;
    }

The "done with copy" log is never seen in the log, I think the code stucks in EntityUtils.toByteArray(entity). I don't know if this makes sense, but it seems to me that the server is giving me the "play" streaming instead of "file" streaming. Anyway, it's clear to me that I'm doing something wrong but I don't know what and I've been trying everything for 4 days. Anyone knows the right way?.

Rafa J
  • 61
  • 9

0 Answers0