From 2f926c8c5f2c798187c6adc4bed35b08cedefa5e Mon Sep 17 00:00:00 2001 From: Gabor Szanto <> Date: Sun, 3 May 2020 23:26:30 +0200 Subject: [PATCH] Added PTZ support, improved discovery, and refactored code and coroutines. --- build.gradle.kts | 36 ++++++++++-- gradlew | 0 .../java/be/teletask/onvif/OnvifExecutor.java | 58 +++++++++---------- .../java/be/teletask/onvif/OnvifManager.java | 50 +++++++++++----- .../java/be/teletask/onvif/OnvifUtils.java | 40 ++++++++++++- .../be/teletask/onvif/OnvifXMLBuilder.java | 34 +++++------ .../OnvifDeviceInformationListener.java | 15 ----- .../listeners/OnvifMediaProfilesListener.java | 17 ------ .../OnvifMediaStreamURIListener.java | 15 ----- .../listeners/OnvifResponseListener.java | 3 +- .../listeners/OnvifServicesListener.java | 15 ----- .../java/be/teletask/onvif/models/Device.java | 29 +++++++++- .../onvif/models/DiscoveryPacket.java | 4 +- .../teletask/onvif/models/DiscoveryType.java | 3 +- .../be/teletask/onvif/models/OnvifDevice.java | 2 - .../be/teletask/onvif/models/OnvifType.java | 6 +- .../onvif/parsers/DiscoveryParser.java | 42 ++++++++++---- .../onvif/requests/AbsoluteMoveRequest.java | 49 ++++++++++++++++ .../onvif/requests/ContinuousMoveRequest.java | 50 ++++++++++++++++ .../requests/GetDeviceInformationRequest.java | 10 ++-- .../requests/GetMediaProfilesRequest.java | 12 ++-- .../onvif/requests/GetMediaStreamRequest.java | 9 ++- .../onvif/requests/GetServicesRequest.java | 10 ++-- .../teletask/onvif/requests/OnvifRequest.java | 21 ++++++- .../onvif/requests/RelativeMoveRequest.java | 52 +++++++++++++++++ .../teletask/onvif/requests/StopRequest.java | 46 +++++++++++++++ .../onvif/responses/OnvifResponse.java | 6 +- .../kotlin/be/teletask/onvif/Extensions.kt | 27 +++++---- src/main/kotlin/be/teletask/onvif/Main.kt | 21 +++++++ .../teletask/onvif/coroutines/Coroutines.kt | 43 +++++--------- .../onvif/requests/GetSnapshotUriRequest.kt | 8 +-- 31 files changed, 516 insertions(+), 217 deletions(-) mode change 100644 => 100755 gradlew delete mode 100644 src/main/java/be/teletask/onvif/listeners/OnvifDeviceInformationListener.java delete mode 100644 src/main/java/be/teletask/onvif/listeners/OnvifMediaProfilesListener.java delete mode 100644 src/main/java/be/teletask/onvif/listeners/OnvifMediaStreamURIListener.java delete mode 100644 src/main/java/be/teletask/onvif/listeners/OnvifServicesListener.java create mode 100644 src/main/java/be/teletask/onvif/requests/AbsoluteMoveRequest.java create mode 100644 src/main/java/be/teletask/onvif/requests/ContinuousMoveRequest.java create mode 100644 src/main/java/be/teletask/onvif/requests/RelativeMoveRequest.java create mode 100644 src/main/java/be/teletask/onvif/requests/StopRequest.java create mode 100644 src/main/kotlin/be/teletask/onvif/Main.kt diff --git a/build.gradle.kts b/build.gradle.kts index 1c51889..f3674a6 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,5 +1,8 @@ plugins { - kotlin("jvm") version "1.3.21" + kotlin("jvm") version "1.3.72" + id("com.jfrog.bintray") version "1.8.5" + `maven-publish` + publishing maven } @@ -9,7 +12,7 @@ repositories { } group = "be.teletask.onvif" -version = "1.0.3" +version = "1.1.5" dependencies { implementation(kotlin("stdlib-jdk8")) @@ -17,7 +20,32 @@ dependencies { implementation("net.sf.kxml", "kxml2", "2.3.0") implementation("com.squareup.okhttp3", "okhttp", "3.11.0") implementation("com.burgstaller", "okhttp-digest", "1.18") - implementation("org.jetbrains.kotlinx", "kotlinx-coroutines-core", "1.1.1") + implementation("org.jetbrains.kotlinx", "kotlinx-coroutines-core", "1.3.4") +} + +publishing { + publications { + register("mavenJava") { + from(components["java"]) + } + } +} + +bintray { + user = System.getenv("bintrayUser") + key = System.getenv("bintrayApiKey") + setPublications("mavenJava") + with(pkg) { + repo = "maven" + name = "onvif-java" + desc = "ONVIF client library for Java and Kotlin" + userOrg = "szantogab" + setLicenses("MIT") + vcsUrl = "https://github.com/szantogab/ONVIF-Java" + with(version) { + name = project.version.toString() + } + } } val sourcesJar by tasks.creating(Jar::class) { @@ -25,4 +53,4 @@ val sourcesJar by tasks.creating(Jar::class) { from(sourceSets["main"].allSource) } -artifacts.add("archives", sourcesJar) \ No newline at end of file +artifacts.add("archives", sourcesJar) diff --git a/gradlew b/gradlew old mode 100644 new mode 100755 diff --git a/src/main/java/be/teletask/onvif/OnvifExecutor.java b/src/main/java/be/teletask/onvif/OnvifExecutor.java index 6a009f4..6ab51c1 100644 --- a/src/main/java/be/teletask/onvif/OnvifExecutor.java +++ b/src/main/java/be/teletask/onvif/OnvifExecutor.java @@ -3,8 +3,11 @@ import be.teletask.onvif.listeners.OnvifResponseListener; import be.teletask.onvif.models.OnvifDevice; import be.teletask.onvif.models.OnvifServices; -import be.teletask.onvif.parsers.*; -import be.teletask.onvif.requests.*; +import be.teletask.onvif.parsers.GetDeviceInformationParser; +import be.teletask.onvif.parsers.GetMediaProfilesParser; +import be.teletask.onvif.parsers.GetMediaStreamParser; +import be.teletask.onvif.parsers.GetServicesParser; +import be.teletask.onvif.requests.OnvifRequest; import be.teletask.onvif.responses.OnvifResponse; import com.burgstaller.okhttp.AuthenticationCacheInterceptor; import com.burgstaller.okhttp.CachingAuthenticatorDecorator; @@ -14,7 +17,6 @@ import okhttp3.*; import okio.Buffer; - import java.io.IOException; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -64,7 +66,7 @@ public class OnvifExecutor { * @param device * @param request */ - void sendRequest(OnvifDevice device, OnvifRequest request) { + void sendRequest(OnvifDevice device, OnvifRequest request) { credentials.setUserName(device.getUsername()); credentials.setPassword(device.getPassword()); reqBody = RequestBody.create(reqBodyType, OnvifXMLBuilder.getSoapHeader() + request.getXml() + OnvifXMLBuilder.getEnvelopeEnd()); @@ -84,17 +86,15 @@ public void setOnvifResponseListener(OnvifResponseListener onvifResponseListener this.onvifResponseListener = onvifResponseListener; } - private void performXmlRequest(OnvifDevice device, OnvifRequest request, Request xmlRequest) { - if (xmlRequest == null) - return; + private void performXmlRequest(OnvifDevice device, OnvifRequest request, Request xmlRequest) { + if (xmlRequest == null) return; client.newCall(xmlRequest) .enqueue(new Callback() { @Override public void onResponse(Call call, Response xmlResponse) throws IOException { - - OnvifResponse response = new OnvifResponse(request); + OnvifResponse response = new OnvifResponse(request); ResponseBody xmlBody = xmlResponse.body(); if (xmlResponse.code() == 200 && xmlBody != null) { @@ -108,49 +108,49 @@ public void onResponse(Call call, Response xmlResponse) throws IOException { if (xmlBody != null) errorMessage = xmlBody.string(); - onvifResponseListener.onError(device, xmlResponse.code(), errorMessage); + if (request.getListener() != null) + request.getListener().onError(new OnvifRequest.OnvifException(device, xmlResponse.code(), errorMessage)); + if (onvifResponseListener != null) + onvifResponseListener.onError(new OnvifRequest.OnvifException(device, xmlResponse.code(), errorMessage)); } @Override public void onFailure(Call call, IOException e) { - onvifResponseListener.onError(device, -1, e.getMessage()); + if (request.getListener() != null) + request.getListener().onError(new OnvifRequest.OnvifException(device, -1, e.getMessage())); + if (onvifResponseListener != null) + onvifResponseListener.onError(new OnvifRequest.OnvifException(device, -1, e.getMessage())); } - }); } - private void parseResponse(OnvifDevice device, OnvifResponse response) { + private void parseResponse(OnvifDevice device, OnvifResponse response) { + Object data = null; switch (response.request().getType()) { case GET_SERVICES: OnvifServices path = new GetServicesParser().parse(response); device.setPath(path); - ((GetServicesRequest) response.request()).getListener().onServicesReceived(device, path); + data = path; break; case GET_DEVICE_INFORMATION: - ((GetDeviceInformationRequest) response.request()).getListener().onDeviceInformationReceived(device, - new GetDeviceInformationParser().parse(response)); + data = new GetDeviceInformationParser().parse(response); break; case GET_MEDIA_PROFILES: - ((GetMediaProfilesRequest) response.request()).getListener().onMediaProfilesReceived(device, - new GetMediaProfilesParser().parse(response)); + data = new GetMediaProfilesParser().parse(response); break; case GET_STREAM_URI: - GetMediaStreamRequest streamRequest = (GetMediaStreamRequest) response.request(); - streamRequest.getListener().onMediaStreamURIReceived(device, streamRequest.getMediaProfile(), - new GetMediaStreamParser().parse(response)); - break; case GET_SNAPSHOT_URI: - GetSnapshotUriRequest snapshotRequest = (GetSnapshotUriRequest) response.request(); - snapshotRequest.getListener().onMediaSnapshotURIReceived(device, snapshotRequest.getProfile(), - new GetMediaStreamParser().parse(response)); - break; + data = new GetMediaStreamParser().parse(response); + break; default: onvifResponseListener.onResponse(device, response); break; } + + response.request().getListener().onSuccess(device, data); } - private Request buildOnvifRequest(OnvifDevice device, OnvifRequest request) { + private Request buildOnvifRequest(OnvifDevice device, OnvifRequest request) { return new Request.Builder() .url(getUrlForRequest(device, request)) .addHeader("Content-Type", "text/xml; charset=utf-8") @@ -158,11 +158,11 @@ private Request buildOnvifRequest(OnvifDevice device, OnvifRequest request) { .build(); } - private String getUrlForRequest(OnvifDevice device, OnvifRequest request) { + private String getUrlForRequest(OnvifDevice device, OnvifRequest request) { return device.getHostName() + getPathForRequest(device, request); } - private String getPathForRequest(OnvifDevice device, OnvifRequest request) { + private String getPathForRequest(OnvifDevice device, OnvifRequest request) { switch (request.getType()) { case GET_SERVICES: return device.getPath().getServicesPath(); diff --git a/src/main/java/be/teletask/onvif/OnvifManager.java b/src/main/java/be/teletask/onvif/OnvifManager.java index 3d68798..2fbf4c0 100644 --- a/src/main/java/be/teletask/onvif/OnvifManager.java +++ b/src/main/java/be/teletask/onvif/OnvifManager.java @@ -2,10 +2,14 @@ import be.teletask.onvif.listeners.*; import be.teletask.onvif.models.OnvifDevice; +import be.teletask.onvif.models.OnvifDeviceInformation; import be.teletask.onvif.models.OnvifMediaProfile; +import be.teletask.onvif.models.OnvifServices; import be.teletask.onvif.requests.*; import be.teletask.onvif.responses.OnvifResponse; +import java.util.List; + /** * Created by Tomas Verhelst on 03/09/2018. @@ -31,32 +35,52 @@ private OnvifManager(OnvifResponseListener onvifResponseListener) { } //Methods - public void getServices(OnvifDevice device, OnvifServicesListener listener) { - OnvifRequest request = new GetServicesRequest(listener); + public void getServices(OnvifDevice device, OnvifRequest.Listener listener) { + final GetServicesRequest request = new GetServicesRequest(listener); + executor.sendRequest(device, request); + } + + public void getDeviceInformation(OnvifDevice device, OnvifRequest.Listener listener) { + final GetDeviceInformationRequest request = new GetDeviceInformationRequest(listener); + executor.sendRequest(device, request); + } + + public void getMediaProfiles(OnvifDevice device, OnvifRequest.Listener> listener) { + final GetMediaProfilesRequest request = new GetMediaProfilesRequest(listener); + executor.sendRequest(device, request); + } + + public void getMediaStreamURI(OnvifDevice device, OnvifMediaProfile profile, OnvifRequest.Listener listener) { + final GetMediaStreamRequest request = new GetMediaStreamRequest(profile, listener); + executor.sendRequest(device, request); + } + + public void getMediaSnapshotURI(OnvifDevice device, OnvifMediaProfile profile, OnvifRequest.Listener listener) { + final GetSnapshotUriRequest request = new GetSnapshotUriRequest(profile, listener); executor.sendRequest(device, request); } - public void getDeviceInformation(OnvifDevice device, OnvifDeviceInformationListener listener) { - OnvifRequest request = new GetDeviceInformationRequest(listener); + public void ptzContinuousMove(OnvifDevice device, String profileToken, Double velocityX, Double velocityY, Double velocityZ, Integer timeout, OnvifRequest.Listener listener) { + final ContinuousMoveRequest request = new ContinuousMoveRequest(profileToken, timeout, velocityX, velocityY, velocityZ, listener); executor.sendRequest(device, request); } - public void getMediaProfiles(OnvifDevice device, OnvifMediaProfilesListener listener) { - OnvifRequest request = new GetMediaProfilesRequest(listener); + public void ptzRelativeMove(OnvifDevice device, String profileToken, Double translationX, Double translationY, Double zoom, OnvifRequest.Listener listener) { + final RelativeMoveRequest request = new RelativeMoveRequest(profileToken, translationX, translationY, zoom, listener); executor.sendRequest(device, request); } - public void getMediaStreamURI(OnvifDevice device, OnvifMediaProfile profile, OnvifMediaStreamURIListener listener) { - OnvifRequest request = new GetMediaStreamRequest(profile, listener); + public void ptzAbsoluteMove(OnvifDevice device, String profileToken, Double positionX, Double positionY, Double zoom, OnvifRequest.Listener listener) { + final AbsoluteMoveRequest request = new AbsoluteMoveRequest(profileToken, positionX, positionY, zoom, listener); executor.sendRequest(device, request); } - public void getMediaSnapshotURI(OnvifDevice device, OnvifMediaProfile profile, OnvifMediaSnapshotURIListener listener) { - OnvifRequest request = new GetSnapshotUriRequest(profile, listener); + public void ptzStop(OnvifDevice device, String profileToken, boolean panTilt, boolean zoom, OnvifRequest.Listener listener) { + final StopRequest request = new StopRequest(profileToken, panTilt, zoom, listener); executor.sendRequest(device, request); } - public void sendOnvifRequest(OnvifDevice device, OnvifRequest request) { + public void sendOnvifRequest(OnvifDevice device, OnvifRequest request) { executor.sendRequest(device, request); } @@ -79,9 +103,9 @@ public void onResponse(OnvifDevice onvifDevice, OnvifResponse response) { } @Override - public void onError(OnvifDevice onvifDevice, int errorCode, String errorMessage) { + public void onError(OnvifRequest.OnvifException exception) { if (onvifResponseListener != null) - onvifResponseListener.onError(onvifDevice, errorCode, errorMessage); + onvifResponseListener.onError(exception); } } diff --git a/src/main/java/be/teletask/onvif/OnvifUtils.java b/src/main/java/be/teletask/onvif/OnvifUtils.java index 202e5ce..2dee8ed 100644 --- a/src/main/java/be/teletask/onvif/OnvifUtils.java +++ b/src/main/java/be/teletask/onvif/OnvifUtils.java @@ -6,6 +6,8 @@ import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; +import java.util.Arrays; +import java.util.List; /** * Created by Tomas Verhelst on 03/09/2018. @@ -60,7 +62,25 @@ public static String retrieveXAddr(XmlPullParser xpp) throws IOException, XmlPul * Util method for parsing. * Retrieve the XAddrs from the XmlPullParser given. */ - public static String retrieveXAddrs(XmlPullParser xpp) throws IOException, XmlPullParserException { + public static UriAndScopes retrieveXAddrsAndScopes(XmlPullParser xpp) throws IOException, XmlPullParserException { + String[] scopes = new String[]{}; + String uri = ""; + int eventType = xpp.getEventType(); + while (eventType != XmlPullParser.END_DOCUMENT) { + + if (eventType == XmlPullParser.START_TAG && xpp.getName().equals("Scopes")) { + xpp.next(); + scopes = xpp.getText().split("\\s+"); + uri = OnvifUtils.retrieveXaddr(xpp); + break; + } + eventType = xpp.next(); + } + + return new UriAndScopes(uri, Arrays.asList(scopes)); + } + + private static String retrieveXaddr(XmlPullParser xpp) throws IOException, XmlPullParserException { String result = ""; int eventType = xpp.getEventType(); while (eventType != XmlPullParser.END_DOCUMENT) { @@ -68,7 +88,6 @@ public static String retrieveXAddrs(XmlPullParser xpp) throws IOException, XmlPu if (eventType == XmlPullParser.START_TAG && xpp.getName().equals("XAddrs")) { xpp.next(); result = xpp.getText(); - break; } eventType = xpp.next(); } @@ -76,5 +95,22 @@ public static String retrieveXAddrs(XmlPullParser xpp) throws IOException, XmlPu return result; } + public static class UriAndScopes { + private String uri; + private List scopes; + + public UriAndScopes(String uri, List scopes) { + this.uri = uri; + this.scopes = scopes; + } + + public String getUri() { + return uri; + } + + public List getScopes() { + return scopes; + } + } } diff --git a/src/main/java/be/teletask/onvif/OnvifXMLBuilder.java b/src/main/java/be/teletask/onvif/OnvifXMLBuilder.java index b6da2c3..d242257 100644 --- a/src/main/java/be/teletask/onvif/OnvifXMLBuilder.java +++ b/src/main/java/be/teletask/onvif/OnvifXMLBuilder.java @@ -5,12 +5,10 @@ * Copyright (c) 2018 TELETASK BVBA. All rights reserved. */ public class OnvifXMLBuilder { - //Constants public static final String TAG = OnvifXMLBuilder.class.getSimpleName(); //Attributes - public static String getSoapHeader() { return "" + ""; } - public static String getDiscoverySoapHeader() { - return "" + - "" + - "" + - "http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe" + - "urn:uuid:%s\n" + - "urn:schemas-xmlsoap-org:ws:2005:04:discovery\n" + - "" + - ""; + public static String getDiscoverySoapHeader(String uuid) { + return "\n" + + "\n" + + " \n" + + " http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe\n" + + " uuid:" + uuid + "\n" + + " \n" + + " http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous\n" + + " \n" + + " urn:schemas-xmlsoap-org:ws:2005:04:discovery\n" + + " \n" + + " \n"; } - public static String getDiscoverySoapBody() { - return ""; + public static String getDiscoverySoapBody(String type) { + return "" + + "dp0:" + type + "\n" + + ""; } } diff --git a/src/main/java/be/teletask/onvif/listeners/OnvifDeviceInformationListener.java b/src/main/java/be/teletask/onvif/listeners/OnvifDeviceInformationListener.java deleted file mode 100644 index e98c770..0000000 --- a/src/main/java/be/teletask/onvif/listeners/OnvifDeviceInformationListener.java +++ /dev/null @@ -1,15 +0,0 @@ -package be.teletask.onvif.listeners; - -import be.teletask.onvif.models.OnvifDevice; -import be.teletask.onvif.models.OnvifDeviceInformation; - - -/** - * Created by Tomas Verhelst on 03/09/2018. - * Copyright (c) 2018 TELETASK BVBA. All rights reserved. - */ -public interface OnvifDeviceInformationListener { - - void onDeviceInformationReceived(OnvifDevice device, OnvifDeviceInformation deviceInformation); - -} diff --git a/src/main/java/be/teletask/onvif/listeners/OnvifMediaProfilesListener.java b/src/main/java/be/teletask/onvif/listeners/OnvifMediaProfilesListener.java deleted file mode 100644 index 1ebf891..0000000 --- a/src/main/java/be/teletask/onvif/listeners/OnvifMediaProfilesListener.java +++ /dev/null @@ -1,17 +0,0 @@ -package be.teletask.onvif.listeners; - -import be.teletask.onvif.models.OnvifDevice; -import be.teletask.onvif.models.OnvifMediaProfile; - - -import java.util.List; - -/** - * Created by Tomas Verhelst on 03/09/2018. - * Copyright (c) 2018 TELETASK BVBA. All rights reserved. - */ -public interface OnvifMediaProfilesListener { - - void onMediaProfilesReceived(OnvifDevice device, List mediaProfiles); - -} diff --git a/src/main/java/be/teletask/onvif/listeners/OnvifMediaStreamURIListener.java b/src/main/java/be/teletask/onvif/listeners/OnvifMediaStreamURIListener.java deleted file mode 100644 index e275398..0000000 --- a/src/main/java/be/teletask/onvif/listeners/OnvifMediaStreamURIListener.java +++ /dev/null @@ -1,15 +0,0 @@ -package be.teletask.onvif.listeners; - -import be.teletask.onvif.models.OnvifDevice; -import be.teletask.onvif.models.OnvifMediaProfile; - - -/** - * Created by Tomas Verhelst on 03/09/2018. - * Copyright (c) 2018 TELETASK BVBA. All rights reserved. - */ -public interface OnvifMediaStreamURIListener { - - void onMediaStreamURIReceived(OnvifDevice device, OnvifMediaProfile profile, String uri); - -} diff --git a/src/main/java/be/teletask/onvif/listeners/OnvifResponseListener.java b/src/main/java/be/teletask/onvif/listeners/OnvifResponseListener.java index d24d4da..a983c43 100644 --- a/src/main/java/be/teletask/onvif/listeners/OnvifResponseListener.java +++ b/src/main/java/be/teletask/onvif/listeners/OnvifResponseListener.java @@ -1,6 +1,7 @@ package be.teletask.onvif.listeners; import be.teletask.onvif.models.OnvifDevice; +import be.teletask.onvif.requests.OnvifRequest; import be.teletask.onvif.responses.OnvifResponse; @@ -12,5 +13,5 @@ public interface OnvifResponseListener { void onResponse(OnvifDevice onvifDevice, OnvifResponse response); - void onError(OnvifDevice onvifDevice, int errorCode, String errorMessage); + void onError(OnvifRequest.OnvifException e); } diff --git a/src/main/java/be/teletask/onvif/listeners/OnvifServicesListener.java b/src/main/java/be/teletask/onvif/listeners/OnvifServicesListener.java deleted file mode 100644 index 55ed8c1..0000000 --- a/src/main/java/be/teletask/onvif/listeners/OnvifServicesListener.java +++ /dev/null @@ -1,15 +0,0 @@ -package be.teletask.onvif.listeners; - -import be.teletask.onvif.models.OnvifDevice; -import be.teletask.onvif.models.OnvifServices; - - -/** - * Created by Tomas Verhelst on 03/09/2018. - * Copyright (c) 2018 TELETASK BVBA. All rights reserved. - */ -public interface OnvifServicesListener { - - void onServicesReceived(OnvifDevice onvifDevice, OnvifServices paths); - -} diff --git a/src/main/java/be/teletask/onvif/models/Device.java b/src/main/java/be/teletask/onvif/models/Device.java index 35a6613..5dfec23 100644 --- a/src/main/java/be/teletask/onvif/models/Device.java +++ b/src/main/java/be/teletask/onvif/models/Device.java @@ -1,7 +1,6 @@ package be.teletask.onvif.models; - import java.util.Locale; /** @@ -9,13 +8,15 @@ * Copyright (c) 2018 TELETASK BVBA. All rights reserved. */ public abstract class Device implements Comparable { - //Constants public static final String TAG = Device.class.getSimpleName(); private static final String FORMAT_HTTP = "http://%s"; //Attributes private String host; + private String name; + private String location; + private String hardware; private String username; private String password; private boolean connected; @@ -61,6 +62,30 @@ public void setConnected(boolean connected) { this.connected = connected; } + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getLocation() { + return location; + } + + public void setLocation(String location) { + this.location = location; + } + + public String getHardware() { + return hardware; + } + + public void setHardware(String hardware) { + this.hardware = hardware; + } + @Override public int compareTo(Device device) { return getHostName().compareTo(device.getHostName()); diff --git a/src/main/java/be/teletask/onvif/models/DiscoveryPacket.java b/src/main/java/be/teletask/onvif/models/DiscoveryPacket.java index f57d016..f1cb933 100644 --- a/src/main/java/be/teletask/onvif/models/DiscoveryPacket.java +++ b/src/main/java/be/teletask/onvif/models/DiscoveryPacket.java @@ -44,9 +44,9 @@ public byte[] getData() { String data = ""; if (mode.equals(DiscoveryMode.ONVIF)) { StringBuilder builder = new StringBuilder(); - String header = String.format(Locale.getDefault(), OnvifXMLBuilder.getDiscoverySoapHeader(), uuid); + String header = OnvifXMLBuilder.getDiscoverySoapHeader(uuid); builder.append(header); - builder.append(OnvifXMLBuilder.getDiscoverySoapBody()); + builder.append(OnvifXMLBuilder.getDiscoverySoapBody("Device")); builder.append(OnvifXMLBuilder.getEnvelopeEnd()); data = builder.toString(); } else if (mode.equals(DiscoveryMode.UPNP)) { diff --git a/src/main/java/be/teletask/onvif/models/DiscoveryType.java b/src/main/java/be/teletask/onvif/models/DiscoveryType.java index b7654db..cc6b6ca 100644 --- a/src/main/java/be/teletask/onvif/models/DiscoveryType.java +++ b/src/main/java/be/teletask/onvif/models/DiscoveryType.java @@ -6,7 +6,8 @@ */ public enum DiscoveryType { DEVICE(0, "Device"), - NETWORK_VIDEO_TRANSMITTER(1, "NetworkVideoTransmitter"); + NETWORK_VIDEO_TRANSMITTER(1, "NetworkVideoTransmitter"), + NETWORK_VIDEO_DISPLAY(2, "NetworkVideoDisplay"); public final int id; public final String type; diff --git a/src/main/java/be/teletask/onvif/models/OnvifDevice.java b/src/main/java/be/teletask/onvif/models/OnvifDevice.java index 57cd239..99e6343 100644 --- a/src/main/java/be/teletask/onvif/models/OnvifDevice.java +++ b/src/main/java/be/teletask/onvif/models/OnvifDevice.java @@ -1,7 +1,6 @@ package be.teletask.onvif.models; - import java.util.ArrayList; import java.util.List; @@ -10,7 +9,6 @@ * Copyright (c) 2018 TELETASK BVBA. All rights reserved. */ public class OnvifDevice extends Device { - //Constants public static final String TAG = OnvifDevice.class.getSimpleName(); diff --git a/src/main/java/be/teletask/onvif/models/OnvifType.java b/src/main/java/be/teletask/onvif/models/OnvifType.java index 7af9c84..1329bfb 100644 --- a/src/main/java/be/teletask/onvif/models/OnvifType.java +++ b/src/main/java/be/teletask/onvif/models/OnvifType.java @@ -10,7 +10,11 @@ public enum OnvifType { GET_DEVICE_INFORMATION("http://www.onvif.org/ver10/device/wsdl"), GET_MEDIA_PROFILES("http://www.onvif.org/ver10/media/wsdl"), GET_STREAM_URI("http://www.onvif.org/ver10/media/wsdl"), - GET_SNAPSHOT_URI("http://www.onvif.org/ver10/media/wsdl"); + GET_SNAPSHOT_URI("http://www.onvif.org/ver10/media/wsdl"), + CONTINUOUS_MOVE("http://www.onvif.org/ver10/media/wsdl"), + ABSOLUTE_MOVE("http://www.onvif.org/ver10/media/wsdl"), + PTZ_STOP("http://www.onvif.org/ver10/media/wsdl"), + RELATIVE_MOVE("http://www.onvif.org/ver10/media/wsdl"); public final String namespace; diff --git a/src/main/java/be/teletask/onvif/parsers/DiscoveryParser.java b/src/main/java/be/teletask/onvif/parsers/DiscoveryParser.java index 6c70793..42625a6 100644 --- a/src/main/java/be/teletask/onvif/parsers/DiscoveryParser.java +++ b/src/main/java/be/teletask/onvif/parsers/DiscoveryParser.java @@ -13,6 +13,7 @@ import java.io.IOException; import java.io.StringReader; +import java.net.URI; import java.util.ArrayList; import java.util.List; @@ -25,10 +26,10 @@ public class DiscoveryParser extends OnvifParser> { //Constants public static final String TAG = DiscoveryParser.class.getSimpleName(); private static final String LINE_END = "\r\n"; - private static String KEY_UPNP_LOCATION = "LOCATION: "; - private static String KEY_UPNP_SERVER = "SERVER: "; - private static String KEY_UPNP_USN = "USN: "; - private static String KEY_UPNP_ST = "ST: "; + private static final String KEY_UPNP_LOCATION = "LOCATION: "; + private static final String KEY_UPNP_SERVER = "SERVER: "; + private static final String KEY_UPNP_USN = "USN: "; + private static final String KEY_UPNP_ST = "ST: "; //Attributes private DiscoveryMode mode; @@ -69,9 +70,17 @@ private List parseOnvif(OnvifResponse response) { getXpp().next(); String type = getXpp().getText(); - if (mode.equals(DiscoveryMode.ONVIF) && type.contains(DiscoveryType.NETWORK_VIDEO_TRANSMITTER.type)) { - String uri = OnvifUtils.retrieveXAddrs(getXpp()); - devices.addAll(parseDevicesFromUri(uri)); + DiscoveryType discoveryType = null; + try { + discoveryType = DiscoveryType.valueOf(type.substring(3).toUpperCase()); + } catch (Exception e) { + // failed to parse type + e.printStackTrace(); + } + + if (mode.equals(DiscoveryMode.ONVIF) && discoveryType != null) { + final OnvifUtils.UriAndScopes uriAndScopes = OnvifUtils.retrieveXAddrsAndScopes(getXpp()); + devices.addAll(parseDevicesFromUriAndScopes(uriAndScopes)); } } @@ -103,11 +112,24 @@ public void setHostName(String hostName) { this.hostName = hostName; } - private List parseDevicesFromUri(String uri) { + private List parseDevicesFromUriAndScopes(OnvifUtils.UriAndScopes uriAndScopes) { List devices = new ArrayList<>(); - String[] uris = uri.split("\\s+"); + String[] uris = uriAndScopes.getUri().split("\\s+"); + for (String address : uris) { - OnvifDevice device = new OnvifDevice(getHostName()); + final URI url = URI.create(address); + final String parsedAddress = url.getScheme() + "://" + url.getHost() + (url.getPort() == 0 ? "" : ":" + url.getPort()); + + OnvifDevice device = new OnvifDevice(parsedAddress); + if (uriAndScopes.getScopes() != null) { + for (String scope : uriAndScopes.getScopes()) { + final int indexOf = scope.lastIndexOf("/") + 1; + if (scope.contains("onvif://www.onvif.org/hardware/")) device.setHardware(scope.substring(indexOf)); + if (scope.contains("onvif://www.onvif.org/location/")) device.setLocation(scope.substring(indexOf)); + if (scope.contains("onvif://www.onvif.org/name/")) device.setName(scope.substring(indexOf)); + } + } + device.addAddress(address); devices.add(device); } diff --git a/src/main/java/be/teletask/onvif/requests/AbsoluteMoveRequest.java b/src/main/java/be/teletask/onvif/requests/AbsoluteMoveRequest.java new file mode 100644 index 0000000..4150ad4 --- /dev/null +++ b/src/main/java/be/teletask/onvif/requests/AbsoluteMoveRequest.java @@ -0,0 +1,49 @@ +package be.teletask.onvif.requests; + +import be.teletask.onvif.models.OnvifType; + +/** + * Created by Gabor Szanto on 02/05/2020. + */ +public class AbsoluteMoveRequest implements OnvifRequest { + //Constants + public static final String TAG = AbsoluteMoveRequest.class.getSimpleName(); + + //Attributes + private final Listener listener; + private String profileToken; + private Double positionX; + private Double positionY; + private Double zoom; + + //Constructors + + public AbsoluteMoveRequest(String profileToken, Double positionX, Double positionY, Double zoom, Listener listener) { + this.listener = listener; + this.profileToken = profileToken; + this.positionX = positionX; + this.positionY = positionY; + this.zoom = zoom; + } + + //Properties + + public Listener getListener() { + return listener; + } + + @Override + public String getXml() { + return "" + + "" + profileToken + "" + + "" + + (positionX != null || positionY != null ? "" :"") + + (zoom != null ? "" : "") + + ""; + } + + @Override + public OnvifType getType() { + return OnvifType.ABSOLUTE_MOVE; + } +} diff --git a/src/main/java/be/teletask/onvif/requests/ContinuousMoveRequest.java b/src/main/java/be/teletask/onvif/requests/ContinuousMoveRequest.java new file mode 100644 index 0000000..f9016bb --- /dev/null +++ b/src/main/java/be/teletask/onvif/requests/ContinuousMoveRequest.java @@ -0,0 +1,50 @@ +package be.teletask.onvif.requests; + +import be.teletask.onvif.models.OnvifType; + +/** + * Created by Gabor Szanto on 02/05/2020. + */ +public class ContinuousMoveRequest implements OnvifRequest { + //Constants + public static final String TAG = ContinuousMoveRequest.class.getSimpleName(); + + //Attributes + private final Listener listener; + private String profileToken; + private Integer timeout; + private Double velocityX; + private Double velocityY; + private Double velocityZ; + + //Constructors + + public ContinuousMoveRequest(String profileToken, Integer timeout, Double velocityX, Double velocityY, Double velocityZ, Listener listener) { + this.listener = listener; + this.profileToken = profileToken; + this.timeout = timeout; + this.velocityX = velocityX; + this.velocityY = velocityY; + this.velocityZ = velocityZ; + } + + //Properties + + public Listener getListener() { + return listener; + } + + @Override + public String getXml() { + return "" + + "" + profileToken + "" + + "" + + (timeout != null ? "PT" + timeout + "S" : "") + + ""; + } + + @Override + public OnvifType getType() { + return OnvifType.CONTINUOUS_MOVE; + } +} diff --git a/src/main/java/be/teletask/onvif/requests/GetDeviceInformationRequest.java b/src/main/java/be/teletask/onvif/requests/GetDeviceInformationRequest.java index 52debb8..e80be8d 100644 --- a/src/main/java/be/teletask/onvif/requests/GetDeviceInformationRequest.java +++ b/src/main/java/be/teletask/onvif/requests/GetDeviceInformationRequest.java @@ -1,6 +1,6 @@ package be.teletask.onvif.requests; -import be.teletask.onvif.listeners.OnvifDeviceInformationListener; +import be.teletask.onvif.models.OnvifDeviceInformation; import be.teletask.onvif.models.OnvifType; @@ -8,23 +8,23 @@ * Created by Tomas Verhelst on 04/09/2018. * Copyright (c) 2018 TELETASK BVBA. All rights reserved. */ -public class GetDeviceInformationRequest implements OnvifRequest { +public class GetDeviceInformationRequest implements OnvifRequest { //Constants public static final String TAG = GetDeviceInformationRequest.class.getSimpleName(); //Attributes - private final OnvifDeviceInformationListener listener; + private final Listener listener; //Constructors - public GetDeviceInformationRequest(OnvifDeviceInformationListener listener) { + public GetDeviceInformationRequest(Listener listener) { super(); this.listener = listener; } //Properties - public OnvifDeviceInformationListener getListener() { + public Listener getListener() { return listener; } diff --git a/src/main/java/be/teletask/onvif/requests/GetMediaProfilesRequest.java b/src/main/java/be/teletask/onvif/requests/GetMediaProfilesRequest.java index 257612f..56cecb0 100644 --- a/src/main/java/be/teletask/onvif/requests/GetMediaProfilesRequest.java +++ b/src/main/java/be/teletask/onvif/requests/GetMediaProfilesRequest.java @@ -1,30 +1,32 @@ package be.teletask.onvif.requests; -import be.teletask.onvif.listeners.OnvifMediaProfilesListener; +import be.teletask.onvif.models.OnvifMediaProfile; import be.teletask.onvif.models.OnvifType; +import java.util.List; + /** * Created by Tomas Verhelst on 04/09/2018. * Copyright (c) 2018 TELETASK BVBA. All rights reserved. */ -public class GetMediaProfilesRequest implements OnvifRequest { +public class GetMediaProfilesRequest implements OnvifRequest> { //Constants public static final String TAG = GetMediaProfilesRequest.class.getSimpleName(); //Attributes - private final OnvifMediaProfilesListener listener; + private final Listener> listener; //Constructors - public GetMediaProfilesRequest(OnvifMediaProfilesListener listener) { + public GetMediaProfilesRequest(Listener> listener) { super(); this.listener = listener; } //Properties - public OnvifMediaProfilesListener getListener() { + public Listener> getListener() { return listener; } diff --git a/src/main/java/be/teletask/onvif/requests/GetMediaStreamRequest.java b/src/main/java/be/teletask/onvif/requests/GetMediaStreamRequest.java index 8e19e29..e5719a9 100644 --- a/src/main/java/be/teletask/onvif/requests/GetMediaStreamRequest.java +++ b/src/main/java/be/teletask/onvif/requests/GetMediaStreamRequest.java @@ -1,6 +1,5 @@ package be.teletask.onvif.requests; -import be.teletask.onvif.listeners.OnvifMediaStreamURIListener; import be.teletask.onvif.models.OnvifMediaProfile; import be.teletask.onvif.models.OnvifType; @@ -9,17 +8,17 @@ * Created by Tomas Verhelst on 04/09/2018. * Copyright (c) 2018 TELETASK BVBA. All rights reserved. */ -public class GetMediaStreamRequest implements OnvifRequest { +public class GetMediaStreamRequest implements OnvifRequest { //Constants public static final String TAG = GetMediaStreamRequest.class.getSimpleName(); //Attributes private final OnvifMediaProfile mediaProfile; - private final OnvifMediaStreamURIListener listener; + private final Listener listener; //Constructors - public GetMediaStreamRequest(OnvifMediaProfile mediaProfile, OnvifMediaStreamURIListener listener) { + public GetMediaStreamRequest(OnvifMediaProfile mediaProfile, Listener listener) { super(); this.mediaProfile = mediaProfile; this.listener = listener; @@ -31,7 +30,7 @@ public OnvifMediaProfile getMediaProfile() { return mediaProfile; } - public OnvifMediaStreamURIListener getListener() { + public Listener getListener() { return listener; } diff --git a/src/main/java/be/teletask/onvif/requests/GetServicesRequest.java b/src/main/java/be/teletask/onvif/requests/GetServicesRequest.java index 6087ba7..26f166c 100644 --- a/src/main/java/be/teletask/onvif/requests/GetServicesRequest.java +++ b/src/main/java/be/teletask/onvif/requests/GetServicesRequest.java @@ -1,6 +1,6 @@ package be.teletask.onvif.requests; -import be.teletask.onvif.listeners.OnvifServicesListener; +import be.teletask.onvif.models.OnvifServices; import be.teletask.onvif.models.OnvifType; @@ -8,23 +8,23 @@ * Created by Tomas Verhelst on 04/09/2018. * Copyright (c) 2018 TELETASK BVBA. All rights reserved. */ -public class GetServicesRequest implements OnvifRequest { +public class GetServicesRequest implements OnvifRequest { //Constants public static final String TAG = GetServicesRequest.class.getSimpleName(); //Attributes - private final OnvifServicesListener listener; + private final Listener listener; //Constructors - public GetServicesRequest(OnvifServicesListener listener) { + public GetServicesRequest(Listener listener) { super(); this.listener = listener; } //Properties - public OnvifServicesListener getListener() { + public Listener getListener() { return listener; } diff --git a/src/main/java/be/teletask/onvif/requests/OnvifRequest.java b/src/main/java/be/teletask/onvif/requests/OnvifRequest.java index b5518b8..f5247a0 100644 --- a/src/main/java/be/teletask/onvif/requests/OnvifRequest.java +++ b/src/main/java/be/teletask/onvif/requests/OnvifRequest.java @@ -1,15 +1,34 @@ package be.teletask.onvif.requests; +import be.teletask.onvif.models.OnvifDevice; import be.teletask.onvif.models.OnvifType; /** * Created by Tomas Verhelst on 03/09/2018. * Copyright (c) 2018 TELETASK BVBA. All rights reserved. */ -public interface OnvifRequest { +public interface OnvifRequest { String getXml(); OnvifType getType(); + Listener getListener(); + + interface Listener { + void onSuccess(OnvifDevice device, T data); + + void onError(OnvifException exception); + } + + class OnvifException extends Exception { + OnvifDevice onvifDevice; + int errorCode; + + public OnvifException(OnvifDevice onvifDevice, int errorCode, String message) { + super(message); + this.onvifDevice = onvifDevice; + this.errorCode = errorCode; + } + } } diff --git a/src/main/java/be/teletask/onvif/requests/RelativeMoveRequest.java b/src/main/java/be/teletask/onvif/requests/RelativeMoveRequest.java new file mode 100644 index 0000000..3a784d1 --- /dev/null +++ b/src/main/java/be/teletask/onvif/requests/RelativeMoveRequest.java @@ -0,0 +1,52 @@ +package be.teletask.onvif.requests; + +import be.teletask.onvif.models.OnvifType; + +/** + * Created by Gabor Szanto on 02/05/2020. + */ +public class RelativeMoveRequest implements OnvifRequest { + //Constants + public static final String TAG = RelativeMoveRequest.class.getSimpleName(); + + //Attributes + private String profileToken; + private final Listener listener; + private Double translationX; // pan X + private Double translationY; // pan Y + private Double zoom; // zoom + + //Constructors + public RelativeMoveRequest(String profileToken, Double translationX, Double translationY, Double zoom, Listener listener) { + this.profileToken = profileToken; + this.listener = listener; + this.translationX = translationX; + this.translationY = translationY; + this.zoom = zoom; + } + + //Properties + + public Listener getListener() { + return listener; + } + + @Override + public String getXml() { + return "" + + "" + profileToken + "" + + (translationX != null || translationY != null ? "" : "") + + (zoom != null ? "" : "") + + ""; + } + + @Override + public OnvifType getType() { + return OnvifType.RELATIVE_MOVE; + } + +} +/* +'ProfileToken': this.current_profile['token'], + 'Velocity': { 'x': x, 'y': y, 'z': z }, + 'Timeout': timeout*/ diff --git a/src/main/java/be/teletask/onvif/requests/StopRequest.java b/src/main/java/be/teletask/onvif/requests/StopRequest.java new file mode 100644 index 0000000..b2122c4 --- /dev/null +++ b/src/main/java/be/teletask/onvif/requests/StopRequest.java @@ -0,0 +1,46 @@ +package be.teletask.onvif.requests; + +import be.teletask.onvif.models.OnvifType; + +/** + * Created by Gabor Szanto on 02/05/2020. + */ +public class StopRequest implements OnvifRequest { + //Constants + public static final String TAG = StopRequest.class.getSimpleName(); + + //Attributes + private final Listener listener; + private String profileToken; + private boolean panTilt; + private boolean zoom; + + //Constructors + + public StopRequest(String profileToken, boolean panTilt, boolean zoom, Listener listener) { + this.listener = listener; + this.profileToken = profileToken; + this.panTilt = panTilt; + this.zoom = zoom; + } + + //Properties + + public Listener getListener() { + return listener; + } + + @Override + public String getXml() { + return "" + + "" + profileToken + "" + + "" + panTilt + " " + + "" + zoom + " " + + ""; + } + + @Override + public OnvifType getType() { + return OnvifType.PTZ_STOP; + } +} diff --git a/src/main/java/be/teletask/onvif/responses/OnvifResponse.java b/src/main/java/be/teletask/onvif/responses/OnvifResponse.java index a26a3d3..9fb429d 100644 --- a/src/main/java/be/teletask/onvif/responses/OnvifResponse.java +++ b/src/main/java/be/teletask/onvif/responses/OnvifResponse.java @@ -17,14 +17,14 @@ public class OnvifResponse { private String errorMessage; private String xml; - private OnvifRequest onvifRequest; + private OnvifRequest onvifRequest; //Constructors public OnvifResponse(String xml) { this.xml = xml; } - public OnvifResponse(OnvifRequest onvifRequest) { + public OnvifResponse(OnvifRequest onvifRequest) { this.onvifRequest = onvifRequest; } @@ -62,7 +62,7 @@ public void setXml(String xml) { this.xml = xml; } - public OnvifRequest request() { + public OnvifRequest request() { return onvifRequest; } } diff --git a/src/main/kotlin/be/teletask/onvif/Extensions.kt b/src/main/kotlin/be/teletask/onvif/Extensions.kt index c65fe23..ae26350 100644 --- a/src/main/kotlin/be/teletask/onvif/Extensions.kt +++ b/src/main/kotlin/be/teletask/onvif/Extensions.kt @@ -2,24 +2,27 @@ package be.teletask.onvif import be.teletask.onvif.coroutines.* import be.teletask.onvif.models.OnvifDevice +import be.teletask.onvif.models.OnvifDeviceInformation import be.teletask.onvif.models.OnvifMediaProfile val defaultOnvifManager by lazy { OnvifManager() } -suspend fun OnvifDevice.getInformation(om: OnvifManager = defaultOnvifManager) - = awaitDeviceInformation { om.getDeviceInformation(this, it) } +suspend fun OnvifDevice.getInformation(om: OnvifManager = defaultOnvifManager) = awaitDeviceRequest { om.getDeviceInformation(this, it) } -suspend fun OnvifDevice.getMediaProfiles(om: OnvifManager = defaultOnvifManager) - = awaitDeviceMediaProfiles { om.getMediaProfiles(this, it) } +suspend fun OnvifDevice.getMediaProfiles(om: OnvifManager = defaultOnvifManager) = awaitDeviceRequest> { om.getMediaProfiles(this, it) } -suspend fun OnvifDevice.getMediaStreamUri(profile: OnvifMediaProfile, om: OnvifManager = defaultOnvifManager) - = awaitDeviceMediaStreamUri { om.getMediaStreamURI(this, profile, it) } +suspend fun OnvifDevice.getMediaStreamUri(profile: OnvifMediaProfile, om: OnvifManager = defaultOnvifManager) = awaitDeviceRequest { om.getMediaStreamURI(this, profile, it) } -suspend fun OnvifDevice.getMediaSnapshotUri(profile: OnvifMediaProfile, om: OnvifManager = defaultOnvifManager) - = awaitDeviceMediaSnapshotUri { om.getMediaSnapshotURI(this, profile, it) } +suspend fun OnvifDevice.getMediaSnapshotUri(profile: OnvifMediaProfile, om: OnvifManager = defaultOnvifManager) = awaitDeviceRequest { om.getMediaSnapshotURI(this, profile, it) } -suspend fun OnvifDevice.getAllMediaStreamUris(om: OnvifManager = defaultOnvifManager) = - getMediaProfiles(om).map { getMediaStreamUri(it, om) } +suspend fun OnvifDevice.getAllMediaStreamUris(om: OnvifManager = defaultOnvifManager) = getMediaProfiles(om).map { getMediaStreamUri(it, om) } -suspend fun OnvifDevice.getAllMediaSnapshotUris(om: OnvifManager = defaultOnvifManager) = - getMediaProfiles(om).map { getMediaSnapshotUri(it, om) } \ No newline at end of file +suspend fun OnvifDevice.getAllMediaSnapshotUris(om: OnvifManager = defaultOnvifManager) = getMediaProfiles(om).map { getMediaSnapshotUri(it, om) } + +suspend fun OnvifDevice.ptzContinuousMove(profileToken: String, velocityX: Double, velocityY: Double, velocityZ: Double?, timeout: Int?, om: OnvifManager = defaultOnvifManager) = awaitDeviceRequest { om.ptzContinuousMove(this, profileToken, velocityX, velocityY, velocityZ, timeout, it) } + +suspend fun OnvifDevice.ptzRelativeMove(profileToken: String, translationX: Double?, translationY: Double?, zoom: Double?, om: OnvifManager = defaultOnvifManager) = awaitDeviceRequest { om.ptzRelativeMove(this, profileToken, translationX, translationY, zoom, it) } + +suspend fun OnvifDevice.ptzAbsoluteMove(profileToken: String, positionX: Double?, positionY: Double?, zoom: Double?, om: OnvifManager = defaultOnvifManager) = awaitDeviceRequest { om.ptzAbsoluteMove(this, profileToken, positionX, positionY, zoom, it) } + +suspend fun OnvifDevice.ptzStop(profileToken: String, panTilt: Boolean = true, zoom: Boolean = true, om: OnvifManager = defaultOnvifManager) = awaitDeviceRequest { om.ptzStop(this, profileToken, panTilt, zoom, it) } diff --git a/src/main/kotlin/be/teletask/onvif/Main.kt b/src/main/kotlin/be/teletask/onvif/Main.kt new file mode 100644 index 0000000..5500477 --- /dev/null +++ b/src/main/kotlin/be/teletask/onvif/Main.kt @@ -0,0 +1,21 @@ +package be.teletask.onvif + +import be.teletask.onvif.coroutines.discoverDevices +import be.teletask.onvif.models.OnvifDevice +import kotlinx.coroutines.runBlocking + +fun main() = runBlocking { + val onvifDevices = discoverDevices { discoveryMode = DiscoveryMode.ONVIF }.filterIsInstance(OnvifDevice::class.java) + + val device = onvifDevices.first() + val info = device.getInformation() + val mediaProfiles = device.getMediaProfiles() + device.ptzContinuousMove(mediaProfiles.first().token, -1.0, 1.0, null, 1) + val snapshotUri = device.getMediaSnapshotUri(mediaProfiles.first()) + + device.ptzRelativeMove(mediaProfiles.first().token, 0.1, 0.0, null) + device.ptzAbsoluteMove(mediaProfiles.first().token, 0.1, 0.0, 1.0) + device.ptzStop(mediaProfiles.first().token) + + val info2 = OnvifDevice("192.168.0.132:8888", "admin", "pass").getInformation() +} diff --git a/src/main/kotlin/be/teletask/onvif/coroutines/Coroutines.kt b/src/main/kotlin/be/teletask/onvif/coroutines/Coroutines.kt index 800f75b..38ab695 100644 --- a/src/main/kotlin/be/teletask/onvif/coroutines/Coroutines.kt +++ b/src/main/kotlin/be/teletask/onvif/coroutines/Coroutines.kt @@ -1,22 +1,27 @@ package be.teletask.onvif.coroutines import be.teletask.onvif.DiscoveryManager -import be.teletask.onvif.listeners.* +import be.teletask.onvif.listeners.DiscoveryListener import be.teletask.onvif.models.Device import be.teletask.onvif.models.OnvifDevice -import be.teletask.onvif.models.OnvifDeviceInformation -import be.teletask.onvif.models.OnvifMediaProfile +import be.teletask.onvif.requests.OnvifRequest import kotlinx.coroutines.suspendCancellableCoroutine import kotlin.coroutines.resume -suspend fun awaitDeviceInformation(block: (OnvifDeviceInformationListener) -> Unit): OnvifDeviceInformation = +suspend fun awaitDeviceRequest(block: (OnvifRequest.Listener) -> Unit): T = suspendCancellableCoroutine { cont -> - block(OnvifDeviceInformationListener { _, deviceInformation -> - cont.resume(deviceInformation) + block(object : OnvifRequest.Listener { + override fun onSuccess(device: OnvifDevice?, data: T) { + cont.resume(data) + } + + override fun onError(onvifException: OnvifRequest.OnvifException) { + cont.cancel(onvifException) + } }) } -suspend fun awaitDeviceDiscovery(onDiscoveryStarted: ()->Unit = {}, block: (DiscoveryListener) -> Unit): List = +suspend fun awaitDeviceDiscovery(onDiscoveryStarted: () -> Unit = {}, block: (DiscoveryListener) -> Unit): List = suspendCancellableCoroutine { cont -> block(object : DiscoveryListener { override fun onDevicesFound(devices: List) { @@ -27,31 +32,9 @@ suspend fun awaitDeviceDiscovery(onDiscoveryStarted: ()->Unit = {}, block: (Disc }) } -suspend fun discoverDevices(configure: DiscoveryManager.()->Unit = {}) = DiscoveryManager().run { +suspend fun discoverDevices(configure: DiscoveryManager.() -> Unit = {}) = DiscoveryManager().run { configure() awaitDeviceDiscovery { discover(it) } } - -suspend fun awaitDeviceMediaStreamUri(block: (OnvifMediaStreamURIListener) -> Unit): String = - suspendCancellableCoroutine { cont -> - block(OnvifMediaStreamURIListener { _, _, uri -> - cont.resume(uri) - }) - } - -suspend fun awaitDeviceMediaSnapshotUri(block: (OnvifMediaSnapshotURIListener) -> Unit): String = - suspendCancellableCoroutine { cont -> - block(object : OnvifMediaSnapshotURIListener { - override fun onMediaSnapshotURIReceived(device: OnvifDevice, profile: OnvifMediaProfile, url: String) - = cont.resume(url) - }) - } - -suspend fun awaitDeviceMediaProfiles(block: (OnvifMediaProfilesListener) -> Unit): List = - suspendCancellableCoroutine { cont -> - block(OnvifMediaProfilesListener { _, profiles -> - cont.resume(profiles) - }) - } \ No newline at end of file diff --git a/src/main/kotlin/be/teletask/onvif/requests/GetSnapshotUriRequest.kt b/src/main/kotlin/be/teletask/onvif/requests/GetSnapshotUriRequest.kt index 8887bb1..39e8e42 100644 --- a/src/main/kotlin/be/teletask/onvif/requests/GetSnapshotUriRequest.kt +++ b/src/main/kotlin/be/teletask/onvif/requests/GetSnapshotUriRequest.kt @@ -1,19 +1,19 @@ package be.teletask.onvif.requests -import be.teletask.onvif.listeners.OnvifMediaSnapshotURIListener import be.teletask.onvif.models.OnvifMediaProfile import be.teletask.onvif.models.OnvifType -class GetSnapshotUriRequest(val profile: OnvifMediaProfile, val listener: OnvifMediaSnapshotURIListener) : OnvifRequest { +class GetSnapshotUriRequest(val profile: OnvifMediaProfile, val _listener: OnvifRequest.Listener) : OnvifRequest { //Constants val TAG = GetSnapshotUriRequest::class.java.simpleName - override fun getXml()= """ + override fun getXml() = """ ${profile.token} """.trimIndent() override fun getType() = OnvifType.GET_SNAPSHOT_URI -} \ No newline at end of file + override fun getListener(): OnvifRequest.Listener = _listener +}