├── fastlane ├── metadata │ └── android │ │ ├── en-GB │ │ ├── video.txt │ │ ├── title.txt │ │ ├── short_description.txt │ │ ├── images │ │ │ └── icon.png │ │ ├── changelogs │ │ │ ├── 900.txt │ │ │ ├── 1000.txt │ │ │ ├── 800.txt │ │ │ ├── 12000.txt │ │ │ ├── 12001.txt │ │ │ ├── 12002.txt │ │ │ ├── 500.txt │ │ │ ├── 13000.txt │ │ │ ├── 13001.txt │ │ │ ├── 13002.txt │ │ │ ├── 1100.txt │ │ │ ├── 700.txt │ │ │ └── 600.txt │ │ └── full_description.txt │ │ ├── de-DE │ │ ├── title.txt │ │ ├── short_description.txt │ │ └── full_description.txt │ │ ├── fr │ │ ├── title.txt │ │ ├── short_description.txt │ │ └── full_description.txt │ │ ├── hu │ │ └── title.txt │ │ ├── it-IT │ │ ├── title.txt │ │ ├── short_description.txt │ │ └── full_description.txt │ │ ├── nl-NL │ │ ├── title.txt │ │ ├── short_description.txt │ │ └── full_description.txt │ │ ├── no-NO │ │ ├── title.txt │ │ ├── short_description.txt │ │ └── full_description.txt │ │ ├── pl │ │ └── title.txt │ │ ├── pt-BR │ │ ├── title.txt │ │ ├── short_description.txt │ │ └── full_description.txt │ │ ├── pt │ │ ├── title.txt │ │ ├── short_description.txt │ │ └── full_description.txt │ │ ├── ru │ │ ├── title.txt │ │ ├── short_description.txt │ │ └── full_description.txt │ │ ├── sv │ │ ├── title.txt │ │ ├── short_description.txt │ │ └── full_description.txt │ │ ├── tr │ │ ├── title.txt │ │ ├── short_description.txt │ │ └── full_description.txt │ │ └── zh-HANS-CN │ │ ├── title.txt │ │ ├── short_description.txt │ │ └── full_description.txt ├── Appfile ├── Fastfile ├── CMakeLists.txt ├── prepare_metadata_for_alpha.py └── convert_appstream_to_fastlane.py ├── desktop ├── screenshot1.png ├── screenshot2.png ├── ApplicationIcon-128.png ├── ApplicationIcon-16.png ├── ApplicationIcon-22.png ├── ApplicationIcon-24.png ├── ApplicationIcon-256.png ├── ApplicationIcon-32.png ├── ApplicationIcon-48.png ├── ApplicationIcon-64.png ├── net.meijn.onvifviewer.desktop.in ├── generateIcons.sh ├── CMakeLists.txt ├── ApplicationIcon.svg └── net.meijn.onvifviewer.appdata.xml.in ├── android ├── res │ ├── drawable-hdpi │ │ ├── icon.png │ │ └── onvifviewer_splash.png │ ├── drawable-mdpi │ │ ├── icon.png │ │ └── onvifviewer_splash.png │ ├── drawable-xhdpi │ │ ├── icon.png │ │ └── onvifviewer_splash.png │ ├── drawable-xxhdpi │ │ ├── icon.png │ │ └── onvifviewer_splash.png │ ├── drawable-xxxhdpi │ │ ├── icon.png │ │ └── onvifviewer_splash.png │ ├── values │ │ └── apptheme.xml │ └── drawable │ │ └── splash.xml ├── CMakeLists.txt └── AndroidManifest.xml.in ├── po ├── LINGUAS ├── CMakeLists.txt └── update_translation.sh ├── src ├── qtquickcontrols2.conf ├── qml.qrc ├── AboutPage.qml ├── OnvifStreamViewer.qml ├── +qtav │ └── OnvifStreamViewer.qml ├── onvifdevicemanagermodel.h ├── onvifdevicemanager.h ├── CMakeLists.txt ├── main.qml ├── OnvifCameraViewer.qml ├── onvifsnapshotdownloader.h ├── onvifsnapshotviewer.h ├── onvifdevicediscover.h ├── AddDemoCamera.qml ├── DiscoverCamera.qml ├── onvifsnapshotdownloader.cpp ├── onvifsnapshotviewer.cpp ├── onvifdevicediscover.cpp ├── onvifdevicemanagermodel.cpp ├── onvifdevicemanager.cpp ├── DeviceSettingsPage.qml ├── onvifdevice.h └── main.cpp ├── libOnvifConnect ├── OnvifConnectConfig.cmake.in ├── onvifdeviceservice.h ├── onvifmediaprofile.h ├── onvifmedia2service.h ├── onvifdeviceconnection.h ├── onvifmediaservice.h ├── onvifdeviceconnection_p.h ├── CMakeLists.txt ├── onvifptzservice.h ├── onvifdeviceinformation.h ├── onvifdeviceservice.cpp ├── onvifdeviceinformation.cpp └── onvifmediaprofile.cpp ├── 3rdparty └── wsdl │ ├── www.w3.org │ ├── 2003 │ │ └── 05 │ │ │ └── soap-envelope │ ├── 2004 │ │ └── 08 │ │ │ └── xop │ │ │ └── include │ └── 2005 │ │ ├── 05 │ │ └── xmlmime │ │ └── 08 │ │ └── addressing │ │ └── ws-addr.xsd │ ├── download.sh │ ├── www.onvif.org │ ├── ver10 │ │ ├── pacs │ │ │ └── types.xsd │ │ └── schema │ │ │ └── common.xsd │ └── ver20 │ │ └── analytics │ │ └── rules.xsd │ └── docs.oasis-open.org │ └── wsrf │ └── bf-2.xsd ├── autotests └── CMakeLists.txt ├── .gitignore ├── flatpak └── net.meijn.onvifviewer.yaml ├── cmake └── FindQtAV.cmake ├── .gitlab-ci.yml ├── README.md ├── CMakeLists.txt └── LICENSES └── CC0-1.0.txt /fastlane/metadata/android/en-GB/video.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /fastlane/metadata/android/de-DE/title.txt: -------------------------------------------------------------------------------- 1 | ONVIFViewer -------------------------------------------------------------------------------- /fastlane/metadata/android/en-GB/title.txt: -------------------------------------------------------------------------------- 1 | ONVIFViewer -------------------------------------------------------------------------------- /fastlane/metadata/android/fr/title.txt: -------------------------------------------------------------------------------- 1 | ONVIFViewer -------------------------------------------------------------------------------- /fastlane/metadata/android/hu/title.txt: -------------------------------------------------------------------------------- 1 | ONVIFViewer -------------------------------------------------------------------------------- /fastlane/metadata/android/it-IT/title.txt: -------------------------------------------------------------------------------- 1 | ONVIFViewer -------------------------------------------------------------------------------- /fastlane/metadata/android/nl-NL/title.txt: -------------------------------------------------------------------------------- 1 | ONVIFViewer -------------------------------------------------------------------------------- /fastlane/metadata/android/no-NO/title.txt: -------------------------------------------------------------------------------- 1 | ONVIFViewer -------------------------------------------------------------------------------- /fastlane/metadata/android/pl/title.txt: -------------------------------------------------------------------------------- 1 | ONVIFViewer -------------------------------------------------------------------------------- /fastlane/metadata/android/pt-BR/title.txt: -------------------------------------------------------------------------------- 1 | ONVIFViewer -------------------------------------------------------------------------------- /fastlane/metadata/android/pt/title.txt: -------------------------------------------------------------------------------- 1 | ONVIFViewer -------------------------------------------------------------------------------- /fastlane/metadata/android/ru/title.txt: -------------------------------------------------------------------------------- 1 | ONVIFViewer -------------------------------------------------------------------------------- /fastlane/metadata/android/sv/title.txt: -------------------------------------------------------------------------------- 1 | ONVIFViewer -------------------------------------------------------------------------------- /fastlane/metadata/android/tr/title.txt: -------------------------------------------------------------------------------- 1 | ONVIFViewer -------------------------------------------------------------------------------- /fastlane/metadata/android/zh-HANS-CN/title.txt: -------------------------------------------------------------------------------- 1 | ONVIFViewer -------------------------------------------------------------------------------- /fastlane/metadata/android/zh-HANS-CN/short_description.txt: -------------------------------------------------------------------------------- 1 | 使用ONVIF协议观看和控制网络摄像头 -------------------------------------------------------------------------------- /fastlane/metadata/android/sv/short_description.txt: -------------------------------------------------------------------------------- 1 | Visa och styr nätverkskameror med ONVIF-protokollet -------------------------------------------------------------------------------- /desktop/screenshot1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caspermeijn/onvifviewer/HEAD/desktop/screenshot1.png -------------------------------------------------------------------------------- /desktop/screenshot2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caspermeijn/onvifviewer/HEAD/desktop/screenshot2.png -------------------------------------------------------------------------------- /fastlane/metadata/android/pt/short_description.txt: -------------------------------------------------------------------------------- 1 | Ver e controlar câmaras de rede usando o protocolo ONVIF -------------------------------------------------------------------------------- /fastlane/metadata/android/de-DE/short_description.txt: -------------------------------------------------------------------------------- 1 | Netzwerkkameras mittels ONVIF-Protokoll ansehen und steuern -------------------------------------------------------------------------------- /fastlane/metadata/android/en-GB/short_description.txt: -------------------------------------------------------------------------------- 1 | View and control network cameras using the ONVIF protocol -------------------------------------------------------------------------------- /fastlane/metadata/android/pt-BR/short_description.txt: -------------------------------------------------------------------------------- 1 | Ver e controlar câmeras de rede usando o protocolo ONVIF -------------------------------------------------------------------------------- /fastlane/metadata/android/ru/short_description.txt: -------------------------------------------------------------------------------- 1 | Просмотр и управление сетевыми камерами с помощью протокола ONVIF -------------------------------------------------------------------------------- /desktop/ApplicationIcon-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caspermeijn/onvifviewer/HEAD/desktop/ApplicationIcon-128.png -------------------------------------------------------------------------------- /desktop/ApplicationIcon-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caspermeijn/onvifviewer/HEAD/desktop/ApplicationIcon-16.png -------------------------------------------------------------------------------- /desktop/ApplicationIcon-22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caspermeijn/onvifviewer/HEAD/desktop/ApplicationIcon-22.png -------------------------------------------------------------------------------- /desktop/ApplicationIcon-24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caspermeijn/onvifviewer/HEAD/desktop/ApplicationIcon-24.png -------------------------------------------------------------------------------- /desktop/ApplicationIcon-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caspermeijn/onvifviewer/HEAD/desktop/ApplicationIcon-256.png -------------------------------------------------------------------------------- /desktop/ApplicationIcon-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caspermeijn/onvifviewer/HEAD/desktop/ApplicationIcon-32.png -------------------------------------------------------------------------------- /desktop/ApplicationIcon-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caspermeijn/onvifviewer/HEAD/desktop/ApplicationIcon-48.png -------------------------------------------------------------------------------- /desktop/ApplicationIcon-64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caspermeijn/onvifviewer/HEAD/desktop/ApplicationIcon-64.png -------------------------------------------------------------------------------- /fastlane/metadata/android/fr/short_description.txt: -------------------------------------------------------------------------------- 1 | Afficher et contrôler les caméras en réseau utilisant le protocole ONVIF -------------------------------------------------------------------------------- /fastlane/metadata/android/nl-NL/short_description.txt: -------------------------------------------------------------------------------- 1 | Bekijk en bestuur netwerkcamera's met behulp van het ONVIF protocol -------------------------------------------------------------------------------- /fastlane/metadata/android/no-NO/short_description.txt: -------------------------------------------------------------------------------- 1 | Se på og kontroller nettverkskameraer som bruker ONVIF-protokollen -------------------------------------------------------------------------------- /fastlane/metadata/android/tr/short_description.txt: -------------------------------------------------------------------------------- 1 | ONVIF protokolünü kullanarak ağ kameralarını görüntüleyin ve denetleyin -------------------------------------------------------------------------------- /android/res/drawable-hdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caspermeijn/onvifviewer/HEAD/android/res/drawable-hdpi/icon.png -------------------------------------------------------------------------------- /android/res/drawable-mdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caspermeijn/onvifviewer/HEAD/android/res/drawable-mdpi/icon.png -------------------------------------------------------------------------------- /android/res/drawable-xhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caspermeijn/onvifviewer/HEAD/android/res/drawable-xhdpi/icon.png -------------------------------------------------------------------------------- /android/res/drawable-xxhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caspermeijn/onvifviewer/HEAD/android/res/drawable-xxhdpi/icon.png -------------------------------------------------------------------------------- /android/res/drawable-xxxhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caspermeijn/onvifviewer/HEAD/android/res/drawable-xxxhdpi/icon.png -------------------------------------------------------------------------------- /fastlane/metadata/android/it-IT/short_description.txt: -------------------------------------------------------------------------------- 1 | Visualizzare e controllare le telecamere di rete utilizzando il protocollo ONVIF -------------------------------------------------------------------------------- /po/LINGUAS: -------------------------------------------------------------------------------- 1 | de 2 | fr 3 | hu 4 | it 5 | nb_NO 6 | nl_NL 7 | pl 8 | pt 9 | pt_BR 10 | ru 11 | sv 12 | tr 13 | zh_HANS-CN 14 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-GB/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caspermeijn/onvifviewer/HEAD/fastlane/metadata/android/en-GB/images/icon.png -------------------------------------------------------------------------------- /src/qtquickcontrols2.conf: -------------------------------------------------------------------------------- 1 | [Material] 2 | Primary=#2C7C90 3 | Accent=#2C7C90 4 | Theme=System 5 | 6 | [Universal] 7 | Accent=#2C7C90 8 | Theme=System 9 | -------------------------------------------------------------------------------- /android/res/drawable-hdpi/onvifviewer_splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caspermeijn/onvifviewer/HEAD/android/res/drawable-hdpi/onvifviewer_splash.png -------------------------------------------------------------------------------- /android/res/drawable-mdpi/onvifviewer_splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caspermeijn/onvifviewer/HEAD/android/res/drawable-mdpi/onvifviewer_splash.png -------------------------------------------------------------------------------- /android/res/drawable-xhdpi/onvifviewer_splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caspermeijn/onvifviewer/HEAD/android/res/drawable-xhdpi/onvifviewer_splash.png -------------------------------------------------------------------------------- /android/res/drawable-xxhdpi/onvifviewer_splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caspermeijn/onvifviewer/HEAD/android/res/drawable-xxhdpi/onvifviewer_splash.png -------------------------------------------------------------------------------- /android/res/drawable-xxxhdpi/onvifviewer_splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caspermeijn/onvifviewer/HEAD/android/res/drawable-xxxhdpi/onvifviewer_splash.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-GB/changelogs/900.txt: -------------------------------------------------------------------------------- 1 | This is a minor release, with the following improvements: 2 | - Added donation instructions 3 | - Use breeze icons as fallback theme 4 | -------------------------------------------------------------------------------- /fastlane/metadata/android/zh-HANS-CN/full_description.txt: -------------------------------------------------------------------------------- 1 | 通过此开源应用查看和控制你的使用ONVIF协议的网络摄像头。 2 | 3 | 该应用程序的开发是作为ONVIF Spotlight Challenge的一部分开始的。 4 | 5 | 您可以连接到网络摄像头并查看视频。如果摄像头是可控的,您也可以移动它。 6 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-GB/changelogs/1000.txt: -------------------------------------------------------------------------------- 1 | This is a minor release, with the following improvements: 2 | - Improved support for older devices 3 | - Fixed a potential crash 4 | - Several internal improvements 5 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-GB/changelogs/800.txt: -------------------------------------------------------------------------------- 1 | This is a minor release, with the following improvements: 2 | - Added opening cameras by URL 3 | - Improved snapshot downloading 4 | - Improved translations and added Norwegian 5 | -------------------------------------------------------------------------------- /fastlane/Appfile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2019 Casper Meijn 2 | # 3 | # SPDX-License-Identifier: CC0-1.0 4 | 5 | app_identifier "net.meijn.onvifviewer" 6 | package_name "net.meijn.onvifviewer" 7 | json_key_file "fastlane/api_key.json" 8 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-GB/changelogs/12000.txt: -------------------------------------------------------------------------------- 1 | This is a minor release, with the following improvements: 2 | - Added support for camera discovery 3 | - Fixed video viewer for Android 4 | - Improved translations 5 | - Some small improvements 6 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-GB/changelogs/12001.txt: -------------------------------------------------------------------------------- 1 | This is a minor release, with the following improvements: 2 | - Added support for camera discovery 3 | - Fixed video viewer for Android 4 | - Improved translations 5 | - Some small improvements 6 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-GB/changelogs/12002.txt: -------------------------------------------------------------------------------- 1 | This is a minor release, with the following improvements: 2 | - Added support for camera discovery 3 | - Fixed video viewer for Android 4 | - Improved translations 5 | - Some small improvements 6 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-GB/changelogs/500.txt: -------------------------------------------------------------------------------- 1 | This is a minor release, with the following improvements: 2 | - Added workaround for cameras that don't support relative movement properly 3 | - Added support for zoom'ing 4 | - Improved build system 5 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-GB/changelogs/13000.txt: -------------------------------------------------------------------------------- 1 | This is a minor release, with the following changes: 2 | - Some small improvements 3 | - Now requires Qt 5.12 4 | - Removed option for including breeze icons in the binary, however is it configured as fallback theme 5 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-GB/changelogs/13001.txt: -------------------------------------------------------------------------------- 1 | This is a minor release, with the following changes: 2 | - Some small improvements 3 | - Now requires Qt 5.12 4 | - Removed option for including breeze icons in the binary, however is it configured as fallback theme 5 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-GB/changelogs/13002.txt: -------------------------------------------------------------------------------- 1 | This is a minor release, with the following changes: 2 | - Some small improvements 3 | - Now requires Qt 5.12 4 | - Removed option for including breeze icons in the binary, however is it configured as fallback theme 5 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-GB/changelogs/1100.txt: -------------------------------------------------------------------------------- 1 | This is a minor release, with the following improvements: 2 | - Improved support for older devices 3 | - Show multiple cameras if room available 4 | - Improved translations and added new langagues 5 | - Several internal improvements 6 | -------------------------------------------------------------------------------- /android/res/values/apptheme.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | -------------------------------------------------------------------------------- /libOnvifConnect/OnvifConnectConfig.cmake.in: -------------------------------------------------------------------------------- 1 | # Copyright 2018-2019 Casper Meijn 2 | # SPDX-License-Identifier: CC0-1.0 3 | 4 | @PACKAGE_INIT@ 5 | 6 | find_dependency(Qt5Core @REQUIRED_QT_VERSION@) 7 | 8 | include("${CMAKE_CURRENT_LIST_DIR}/OnvifConnectTargets.cmake") 9 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-GB/changelogs/700.txt: -------------------------------------------------------------------------------- 1 | This is a minor release, with the following improvements: 2 | - Improved UI style by using Kirigami cards 3 | - Improved translations by supporting Weblate 4 | - Made demo cameras optional, by moving them to the add camera button 5 | - Some small improvements 6 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-GB/changelogs/600.txt: -------------------------------------------------------------------------------- 1 | This is a minor release, with the following improvements: 2 | - Renamed internal application name. Note: this causes the configuration file to reset 3 | - Added internationalization support with Brazilian and Dutch translations 4 | - Replaced demo cameras 5 | - Several internal improvements 6 | -------------------------------------------------------------------------------- /fastlane/metadata/android/pt/full_description.txt: -------------------------------------------------------------------------------- 1 | Use esta app open-source para visualizar as suas câmaras de rede a usar o protocolo ONVIF. 2 | 3 | O desenvolvimento desta app foi iniciado como parte do ONVIF Spotlight Desafio. 4 | 5 | Pode conectar-se à sua câmara de rede e ver o vídeo dela. Se a a câmara é controlável, pode movê-la também. 6 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-GB/full_description.txt: -------------------------------------------------------------------------------- 1 | Use this open-source app to view your network cameras using the ONVIF protocol. 2 | 3 | The development of this app was started as part of the ONVIF Spotlight Challenge. 4 | 5 | You can connect to your network camera and view the video of it. If the camera is controllable you can move it as well. 6 | -------------------------------------------------------------------------------- /fastlane/metadata/android/sv/full_description.txt: -------------------------------------------------------------------------------- 1 | Använd det här öppen-källkodsprogrammet för att visa dina nätverkskameror med ONVIF-protokollet. 2 | 3 | Utvecklingen av denna app startades som en del av ONVIF Spotlight Challenge. 4 | 5 | Du kan ansluta till din nätverkskamera och visa videon från den. Om kameran är styrbar kan du flytta den också. 6 | -------------------------------------------------------------------------------- /desktop/net.meijn.onvifviewer.desktop.in: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Version=1.0 3 | Type=Application 4 | Terminal=false 5 | Exec=onvifviewer %u 6 | Name=ONVIFViewer 7 | Icon=net.meijn.onvifviewer 8 | Comment=View and control network cameras using the ONVIF protocol 9 | Categories=Network;Qt 10 | MimeType=x-scheme-handler/onvif; 11 | StartupWMClass=onvifviewer 12 | -------------------------------------------------------------------------------- /fastlane/metadata/android/no-NO/full_description.txt: -------------------------------------------------------------------------------- 1 | Bruk dette friprogprogrammet for å vise dine nettverkskamera som bruker ONVIF-protokollen. 2 | 3 | Utviklingen av dette programmet ble startet som del av ONVIF Spotlight-utfordringen. 4 | 5 | Du kan koble til ditt nettverkskamera og vise videostrømmen fra det. Hvis kameraet er kontrollerbart kan du bevege det også. 6 | -------------------------------------------------------------------------------- /fastlane/metadata/android/pt-BR/full_description.txt: -------------------------------------------------------------------------------- 1 | Use este aplicativo open-source para visualizar suas câmeras de rede usando o protocolo ONVIF. 2 | 3 | O desenvolvimento deste aplicativo foi iniciado como parte do ONVIF Spotlight Desafio. 4 | 5 | Você pode se conectar à sua câmera de rede e ver o vídeo dela. Se a a câmera é controlável, você pode movê-la também. 6 | -------------------------------------------------------------------------------- /fastlane/metadata/android/ru/full_description.txt: -------------------------------------------------------------------------------- 1 | Используйте это приложение с открытым исходным кодом для просмотра сетевых камер с использованием протокола ONVIF. 2 | 3 | Разработка этого приложения началась в рамках конкурса ONVIF Spotlight Challenge. 4 | 5 | Вы можете подключиться к сетевой камере и просматривать видео с нее. Если камера управляемая, ее можно перемещать. 6 | -------------------------------------------------------------------------------- /fastlane/metadata/android/de-DE/full_description.txt: -------------------------------------------------------------------------------- 1 | Diese quelloffenen App ermöglicht das Anschauen der eigenen Netzwerkkameras mittels ONVIF-Protokoll. 2 | 3 | Die Entwicklung dieser App wurde als Teil der ONVIF Spotlight Challenge gestartet. 4 | 5 | Mit der eigene Netzwerkkamera verbinden und deren Video ansehen. Sollte die Kamera steuerbar sein, lässt sie sich auch bewegen. 6 | -------------------------------------------------------------------------------- /fastlane/metadata/android/tr/full_description.txt: -------------------------------------------------------------------------------- 1 | ONVIF protokolünü kullanarak ağ kameralarınızı görüntülemek için bu açık kaynaklı uygulamayı kullanın. 2 | 3 | Bu uygulamanın geliştirilmesine ONVIF Spotlight Challenge'ın bir parçası olarak başlandı. 4 | 5 | Ağ kameranıza bağlanabilir ve videosunu görüntüleyebilirsiniz. Kamera denetlenebilir ise, onu hareket de ettirebilirsiniz. 6 | -------------------------------------------------------------------------------- /fastlane/metadata/android/nl-NL/full_description.txt: -------------------------------------------------------------------------------- 1 | Gebruik deze open-bron applicatie voor het bekijken van netwerkcamera's via het ONVIF protocol. 2 | 3 | De ontwikkeling van deze applicatie is gestart als onderdeel van de ONVIF Spotlight Challange. 4 | 5 | Je kan verbinden met jouw netwerkcamera en het beeld daarvan bekijken. Als de camera bedienbaar is, dan kan je hem bewegen. 6 | -------------------------------------------------------------------------------- /fastlane/metadata/android/fr/full_description.txt: -------------------------------------------------------------------------------- 1 | Utilisez cette application open-source pour visualiser vos caméras IP à l'aide du protocole ONVIF. 2 | 3 | Le développement de cette application a été lancé dans le cadre du Spotlight ONVIF Challenge. 4 | 5 | Vous pouvez vous connecter à votre caméra réseau et visionner la vidéo de celle-ci. Si la caméra est contrôlable, vous pouvez également la déplacer. 6 | -------------------------------------------------------------------------------- /fastlane/metadata/android/it-IT/full_description.txt: -------------------------------------------------------------------------------- 1 | Utilizzare questa applicazione open source per visualizzare le telecamere di rete utilizzando il protocollo ONVIF. 2 | 3 | Lo sviluppo di questa applicazione è stato avviato nell'ambito dell'ONVIF Spotlight Challange. 4 | 5 | È possibile connettersi alla telecamera di rete e visualizzarne il video. Se la telecamera è controllabile è possibile spostarla. 6 | -------------------------------------------------------------------------------- /android/res/drawable/splash.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /3rdparty/wsdl/www.w3.org/2004/08/xop/include: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /fastlane/Fastfile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2019 Casper Meijn 2 | # 3 | # SPDX-License-Identifier: CC0-1.0 4 | 5 | lane :upload_alpha do 6 | sh("./prepare_metadata_for_alpha.py", "--manifest=" + ENV["APK_PATH"] + "/AndroidManifest-arm.xml", "--fastlane=metadata") 7 | sh("./prepare_metadata_for_alpha.py", "--manifest=" + ENV["APK_PATH"] + "/AndroidManifest-aarch64.xml", "--fastlane=metadata") 8 | upload_to_play_store(track: 'alpha', apk_paths: [ ENV["APK_PATH"] + "/onvifviewer_build_apk-release-signed-arm.apk", ENV["APK_PATH"] + "/onvifviewer_build_apk-release-signed-aarch64.apk" ], check_superseded_tracks: true) 9 | end 10 | -------------------------------------------------------------------------------- /src/qml.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | main.qml 6 | qtquickcontrols2.conf 7 | OnvifCameraViewer.qml 8 | OnvifStreamViewer.qml 9 | +qtav/OnvifStreamViewer.qml 10 | DeviceSettingsPage.qml 11 | OverviewPage.qml 12 | DeviceViewerPage.qml 13 | AddDemoCamera.qml 14 | DiscoverCamera.qml 15 | AboutPage.qml 16 | 17 | 18 | -------------------------------------------------------------------------------- /3rdparty/wsdl/download.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -eu 3 | # Copyright (C) 2019 Casper Meijn 4 | # 5 | # SPDX-License-Identifier: CC0-1.0 6 | 7 | rm -rf docs.oasis-open.org www.onvif.org www.w3.org 8 | wget -r --accept wsdl,xsd -I specs,ver10,ver20 https://www.onvif.org/profiles/specifications/ 9 | wget -r http://www.w3.org/2005/05/xmlmime 10 | wget -r http://www.w3.org/2003/05/soap-envelope 11 | wget -r http://docs.oasis-open.org/wsn/b-2.xsd 12 | wget -r http://www.w3.org/2004/08/xop/include 13 | wget -r http://www.w3.org/2005/08/addressing/ws-addr.xsd 14 | wget -r http://docs.oasis-open.org/wsn/t-1 15 | wget -r http://docs.oasis-open.org/wsrf/bf-2.xsd 16 | wget -r http://docs.oasis-open.org/wsn/t-1.xsd 17 | wget -r http://www.w3.org/2001/xml.xsd 18 | mv www.onvif.org/ver20/media/wsdl/media.wsdl www.onvif.org/ver20/media/wsdl/media2.wsdl 19 | -------------------------------------------------------------------------------- /autotests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2018 Casper Meijn 2 | # SPDX-License-Identifier: GPL-3.0-or-later 3 | # 4 | # This program is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | cmake_minimum_required(VERSION 3.7) 18 | 19 | add_test(NAME startup COMMAND onvifviewer --test startup) 20 | -------------------------------------------------------------------------------- /src/AboutPage.qml: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2019 Casper Meijn 2 | * SPDX-License-Identifier: GPL-3.0-or-later 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | import org.kde.kirigami 2.6 as Kirigami 18 | 19 | Kirigami.AboutPage { 20 | aboutData: onvifviewerAboutData 21 | } 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2019 Casper Meijn 2 | # 3 | # SPDX-License-Identifier: CC0-1.0 4 | 5 | # CMake 6 | CMakeCache.txt 7 | CMakeFiles 8 | CMakeScripts 9 | Testing 10 | Makefile 11 | cmake_install.cmake 12 | install_manifest.txt 13 | compile_commands.json 14 | CTestTestfile.cmake 15 | 16 | # C++ objects and libs 17 | *.slo 18 | *.lo 19 | *.o 20 | *.a 21 | *.la 22 | *.lai 23 | *.so 24 | *.dll 25 | *.dylib 26 | 27 | # Qt-es 28 | object_script.*.Release 29 | object_script.*.Debug 30 | *_plugin_import.cpp 31 | /.qmake.cache 32 | /.qmake.stash 33 | *.pro.user 34 | *.pro.user.* 35 | *.qbs.user 36 | *.qbs.user.* 37 | *.moc 38 | moc_*.cpp 39 | moc_*.h 40 | qrc_*.cpp 41 | ui_*.h 42 | *.qmlc 43 | *.jsc 44 | Makefile* 45 | *build-* 46 | 47 | # Qt unit tests 48 | target_wrapper.* 49 | 50 | # QtCreator 51 | *.autosave 52 | 53 | # QtCreator Qml 54 | *.qmlproject.user 55 | *.qmlproject.user.* 56 | 57 | # QtCreator CMake 58 | CMakeLists.txt.user* 59 | 60 | # KDevelop 61 | *.kdev4 62 | 63 | # fastlane 64 | fastlane/api*.json 65 | 66 | # Flatpak 67 | .flatpak-builder 68 | flatpak/build 69 | flatpak/repo 70 | 71 | # Android 72 | android/AndroidManifest.xml 73 | -------------------------------------------------------------------------------- /flatpak/net.meijn.onvifviewer.yaml: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2019 Casper Meijn 2 | # 3 | # SPDX-License-Identifier: CC0-1.0 4 | --- 5 | app-id: net.meijn.onvifviewer 6 | runtime: org.kde.Platform 7 | runtime-version: '5.15' 8 | sdk: org.kde.Sdk 9 | command: onvifviewer 10 | tags: 11 | - nightly 12 | desktop-file-name-suffix: " (Nightly)" 13 | finish-args: 14 | - "--share=ipc" 15 | - "--socket=x11" 16 | - "--socket=wayland" 17 | - "--device=dri" 18 | - "--share=network" 19 | separate-locales: false 20 | modules: 21 | 22 | - name: kdsoap 23 | buildsystem: cmake-ninja 24 | builddir: true 25 | config-opts: 26 | - "-DKDSoap_EXAMPLES=false" 27 | sources: 28 | - type: git 29 | url: https://github.com/KDAB/KDSoap.git 30 | tag: kdsoap-1.10.0 31 | commit: ea2d532bcef8a84991b137b0bfc1716d28b2eb67 32 | 33 | - name: kdsoap-ws-discovery-client 34 | buildsystem: cmake-ninja 35 | builddir: true 36 | sources: 37 | - type: git 38 | url: https://gitlab.com/caspermeijn/kdsoap-ws-discovery-client.git 39 | branch: master 40 | 41 | - name: onvifviewer 42 | buildsystem: cmake-ninja 43 | builddir: true 44 | sources: 45 | - type: dir 46 | path: ".." 47 | skip: 48 | - ".git" 49 | -------------------------------------------------------------------------------- /desktop/generateIcons.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -eu 3 | # Copyright 2019 Casper Meijn 4 | # SPDX-License-Identifier: CC0-1.0 5 | 6 | generate_application_icon() { 7 | SIZE=$1 8 | inkscape ApplicationIcon.svg --export-png "ApplicationIcon-$SIZE.png" --export-width "$SIZE" 9 | } 10 | 11 | generate_application_icon 16 12 | generate_application_icon 22 13 | generate_application_icon 24 14 | generate_application_icon 32 15 | generate_application_icon 48 16 | generate_application_icon 64 17 | generate_application_icon 128 18 | generate_application_icon 256 19 | 20 | generate_android_icon() { 21 | SIZE=$1 22 | DENSITY=$2 23 | inkscape ApplicationIcon.svg --export-png "../android/res/drawable-$DENSITY/icon.png" --export-width "$SIZE" 24 | } 25 | 26 | generate_android_icon 48 mdpi 27 | generate_android_icon 72 hdpi 28 | generate_android_icon 96 xhdpi 29 | generate_android_icon 144 xxhdpi 30 | generate_android_icon 192 xxxhdpi 31 | 32 | generate_android_splash() { 33 | SIZE=$1 34 | DENSITY=$2 35 | inkscape ApplicationIcon.svg --export-png "../android/res/drawable-$DENSITY/onvifviewer_splash.png" --export-width "$SIZE" --export-background "#2C7C90" 36 | } 37 | 38 | generate_android_splash 200 mdpi 39 | generate_android_splash 300 hdpi 40 | generate_android_splash 400 xhdpi 41 | generate_android_splash 600 xxhdpi 42 | generate_android_splash 800 xxxhdpi 43 | -------------------------------------------------------------------------------- /fastlane/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2019 Casper Meijn 2 | # SPDX-License-Identifier: GPL-3.0-or-later 3 | # 4 | # This program is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | cmake_minimum_required(VERSION 3.7) 18 | 19 | set(_appDataFile ${CMAKE_CURRENT_BINARY_DIR}/../desktop/net.meijn.onvifviewer.appdata.xml) 20 | set(_fastlaneMetadata ${CMAKE_CURRENT_SOURCE_DIR}/metadata/android/) 21 | add_custom_command( 22 | OUTPUT ${_fastlaneMetadata} 23 | COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/convert_appstream_to_fastlane.py --appstream ${_appDataFile} --fastlane ${_fastlaneMetadata} 24 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 25 | DEPENDS app-data ${_appDataFile}) 26 | add_custom_target(fastlane-metadata DEPENDS ${_fastlaneMetadata}) 27 | -------------------------------------------------------------------------------- /po/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2018 Casper Meijn 2 | # SPDX-License-Identifier: GPL-3.0-or-later 3 | # 4 | # This program is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | cmake_minimum_required(VERSION 3.7) 18 | 19 | file(GLOB PO_FILES *.po) 20 | SET(MO_FILES) 21 | foreach(_poFile ${PO_FILES}) 22 | get_filename_component(_langCode ${_poFile} NAME_WE) 23 | set(_moFile ${CMAKE_CURRENT_BINARY_DIR}/${_langCode}.mo) 24 | add_custom_command( 25 | OUTPUT ${_moFile} 26 | COMMAND ${GETTEXT_MSGFMT_EXECUTABLE} --check --use-fuzzy -o ${_langCode}.mo ${_poFile} 27 | DEPENDS ${_poFile}) 28 | install(FILES ${_moFile} DESTINATION ${LOCALE_INSTALL_DIR}/${_langCode}/LC_MESSAGES/ RENAME ${PROJECT_NAME}.mo) 29 | list(APPEND MO_FILES ${_moFile}) 30 | endforeach() 31 | add_custom_target(translations ALL DEPENDS ${MO_FILES}) 32 | -------------------------------------------------------------------------------- /src/OnvifStreamViewer.qml: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2018 Casper Meijn 2 | * SPDX-License-Identifier: GPL-3.0-or-later 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | import QtMultimedia 5.9 18 | import QtQuick 2.9 19 | 20 | Item { 21 | id: viewer 22 | 23 | property alias streamUri: video.source 24 | property bool hasError: video.error !== MediaPlayer.NoError 25 | 26 | function isStreamAvailable() { 27 | return video.playbackState === MediaPlayer.PlayingState && video.hasVideo && video.source 28 | } 29 | 30 | onVisibleChanged: { 31 | if(viewer.visible) 32 | video.play() 33 | else 34 | video.stop() 35 | } 36 | 37 | Video { 38 | id: video 39 | muted: true 40 | anchors.fill: parent 41 | 42 | autoLoad: true 43 | autoPlay: true 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/+qtav/OnvifStreamViewer.qml: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2018-2019 Casper Meijn 2 | * SPDX-License-Identifier: GPL-3.0-or-later 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | import QtAV 1.7 18 | import QtQuick 2.9 19 | 20 | Item { 21 | id: viewer 22 | 23 | property alias streamUri: video.source 24 | property bool hasError: video.error !== MediaPlayer.NoError 25 | 26 | function isStreamAvailable() { 27 | return video.playbackState === MediaPlayer.PlayingState && video.hasVideo && video.source 28 | } 29 | 30 | onVisibleChanged: { 31 | if(viewer.visible) 32 | video.play() 33 | else 34 | video.stop() 35 | } 36 | 37 | Video { 38 | id: video 39 | muted: true 40 | anchors.fill: parent 41 | 42 | autoLoad: true 43 | autoPlay: true 44 | } 45 | } 46 | 47 | -------------------------------------------------------------------------------- /libOnvifConnect/onvifdeviceservice.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2018 Casper Meijn 2 | * SPDX-License-Identifier: GPL-3.0-or-later 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | #ifndef ONVIFDEVICESERVICE_H 18 | #define ONVIFDEVICESERVICE_H 19 | 20 | #include "onvifconnect_export.h" 21 | #include "onvifdeviceinformation.h" 22 | #include 23 | 24 | class OnvifDeviceConnection; 25 | 26 | class OnvifDeviceServicePrivate; 27 | class ONVIFCONNECT_EXPORT OnvifDeviceService : public QObject 28 | { 29 | Q_OBJECT 30 | Q_DECLARE_PRIVATE(OnvifDeviceService) 31 | QScopedPointer const d_ptr; 32 | public: 33 | explicit OnvifDeviceService(const QString& soapEndpoint, OnvifDeviceConnection* parent); 34 | ~OnvifDeviceService(); 35 | 36 | void connectToService(); 37 | void disconnectFromService(); 38 | 39 | OnvifDeviceInformation getDeviceInformation(); 40 | 41 | signals: 42 | void deviceInformationAvailable(const OnvifDeviceInformation& deviceInformation); 43 | }; 44 | 45 | #endif // ONVIFDEVICESERVICE_H 46 | -------------------------------------------------------------------------------- /src/onvifdevicemanagermodel.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2018 Casper Meijn 2 | * SPDX-License-Identifier: GPL-3.0-or-later 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | #ifndef ONVIFDEVICEMANAGERMODEL_H 18 | #define ONVIFDEVICEMANAGERMODEL_H 19 | 20 | #include 21 | 22 | class OnvifDevice; 23 | class OnvifDeviceManager; 24 | 25 | class OnvifDeviceManagerModel : public QAbstractListModel 26 | { 27 | Q_OBJECT 28 | public: 29 | explicit OnvifDeviceManagerModel(const OnvifDeviceManager* deviceManager, QObject* parent = nullptr); 30 | 31 | public: 32 | int rowCount(const QModelIndex& parent) const override; 33 | QVariant data(const QModelIndex& index, int role) const override; 34 | QVariant headerData(int section, Qt::Orientation orientation, int role) const override; 35 | QHash roleNames() const override; 36 | 37 | private slots: 38 | void deviceListChanged(); 39 | void deviceChanged(); 40 | 41 | private: 42 | const OnvifDeviceManager* m_deviceManager; 43 | }; 44 | 45 | #endif // ONVIFDEVICEMANAGERMODEL_H 46 | -------------------------------------------------------------------------------- /src/onvifdevicemanager.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2018 Casper Meijn 2 | * SPDX-License-Identifier: GPL-3.0-or-later 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | #ifndef ONVIFDEVICEMANAGER_H 18 | #define ONVIFDEVICEMANAGER_H 19 | 20 | #include 21 | 22 | class OnvifDevice; 23 | 24 | class OnvifDeviceManager : public QObject 25 | { 26 | Q_OBJECT 27 | Q_PROPERTY(QList deviceList READ deviceList NOTIFY deviceListChanged) 28 | Q_PROPERTY(int size READ size NOTIFY deviceListChanged) 29 | public: 30 | explicit OnvifDeviceManager(QObject* parent = nullptr); 31 | 32 | QList deviceList() const; 33 | Q_INVOKABLE OnvifDevice* at(int i); 34 | Q_INVOKABLE int appendDevice(); 35 | Q_INVOKABLE void removeDevice(int i); 36 | Q_INVOKABLE int indexOf(OnvifDevice* device); 37 | int size(); 38 | 39 | OnvifDevice* createNewDevice(); 40 | 41 | signals: 42 | void deviceListChanged(const QList& deviceList); 43 | 44 | public slots: 45 | void loadDevices(); 46 | void saveDevices(); 47 | 48 | private: 49 | QList m_deviceList; 50 | }; 51 | 52 | #endif // ONVIFDEVICEMANAGER_H 53 | -------------------------------------------------------------------------------- /3rdparty/wsdl/www.w3.org/2005/05/xmlmime: -------------------------------------------------------------------------------- 1 | 2 | 19 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2018-2019 Casper Meijn 2 | # SPDX-License-Identifier: GPL-3.0-or-later 3 | # 4 | # This program is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | cmake_minimum_required(VERSION 3.7) 17 | 18 | set(${PROJECT_NAME}_SRCS 19 | "main.cpp" 20 | "onvifdevice.cpp" 21 | "onvifdevicediscover.cpp" 22 | "onvifdevicemanager.cpp" 23 | "onvifdevicemanagermodel.cpp" 24 | "onvifsnapshotdownloader.cpp" 25 | "onvifsnapshotviewer.cpp" 26 | "qml.qrc" 27 | ) 28 | 29 | ecm_setup_version(PROJECT VERSION_HEADER version.h) 30 | add_executable(${PROJECT_NAME} ${${PROJECT_NAME}_SRCS} ${${PROJECT_NAME}_WSDL} ${${PROJECT_NAME}_BREEZE_ICONS}) 31 | 32 | target_link_libraries(${PROJECT_NAME} Qt5::Core Qt5::Svg Qt5::Quick KF5::CoreAddons KF5::Kirigami2 KF5::I18n KDSoap::kdsoap libOnvifConnect) 33 | if(KF5XmlGui_FOUND) 34 | target_link_libraries(${PROJECT_NAME} KF5::XmlGui) 35 | endif() 36 | 37 | if(KDSoapWSDiscoveryClient_FOUND) 38 | target_link_libraries(${PROJECT_NAME} KDSoap::WSDiscoveryClient) 39 | add_definitions(-DWITH_KDSOAP_WSDISCOVERY_CLIENT) 40 | endif() 41 | if(QTAV_FOUND) 42 | target_link_libraries(${PROJECT_NAME} ${QTAV_LIBRARIES}) 43 | add_definitions(-DWITH_QTAV) 44 | endif() 45 | 46 | install(TARGETS ${PROJECT_NAME} ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) 47 | -------------------------------------------------------------------------------- /android/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2019 Casper Meijn 2 | # SPDX-License-Identifier: GPL-3.0-or-later 3 | # 4 | # This program is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | cmake_minimum_required(VERSION 3.7) 18 | 19 | # Make sure that PROJECT_VERSION_PATCH is set in this scope, as this code assumes that it is set. 20 | if(NOT PROJECT_VERSION_PATCH) 21 | set(PROJECT_VERSION_PATCH 0) 22 | endif() 23 | 24 | # Android manifest 25 | if(${PROJECT_VERSION_MINOR} GREATER_EQUAL 100 OR ${PROJECT_VERSION_PATCH} GREATER_EQUAL 100) 26 | message(FATAL_ERROR "Project version is too high, which causes the Android version code to be not ascending") 27 | endif() 28 | message("CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}") 29 | set(PROCESSOR_ANDROID_VERSION_CODE 0) 30 | if (CMAKE_SYSTEM_PROCESSOR MATCHES "^arm") 31 | set(PROCESSOR_ANDROID_VERSION_CODE 1) 32 | elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^aarch64") 33 | set(PROCESSOR_ANDROID_VERSION_CODE 2) 34 | endif () 35 | math(EXPR DEFAULT_ANDROID_VERSION_CODE "${PROJECT_VERSION_MAJOR} * 100000 + ${PROJECT_VERSION_MINOR} * 1000 + ${PROJECT_VERSION_PATCH} * 10 + ${PROCESSOR_ANDROID_VERSION_CODE}") 36 | set(ANDROID_VERSION_CODE "${DEFAULT_ANDROID_VERSION_CODE}" CACHE STRING "The version code to be used when building for Android" FORCE) 37 | configure_file(AndroidManifest.xml.in ${CMAKE_CURRENT_SOURCE_DIR}/AndroidManifest.xml) 38 | -------------------------------------------------------------------------------- /src/main.qml: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2018-2019 Casper Meijn 2 | * SPDX-License-Identifier: GPL-3.0-or-later 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | import org.kde.kirigami 2.6 as Kirigami 18 | import QtQuick 2.9 19 | import net.meijn.onvifviewer 1.0 20 | 21 | Kirigami.ApplicationWindow { 22 | id: root 23 | 24 | property int selectedIndex: 0 25 | property OnvifDevice previewDevice: null 26 | 27 | onPreviewDeviceChanged: { 28 | if(previewDevice) { 29 | selectedIndex = deviceManager.indexOf(previewDevice); 30 | pageStack.push(deviceViewerComponent); 31 | } 32 | } 33 | 34 | contextDrawer: Kirigami.ContextDrawer { 35 | id: contextDrawer 36 | } 37 | pageStack.initialPage: overviewComponent 38 | Component { 39 | id: deviceViewerComponent 40 | DeviceViewerPage{} 41 | } 42 | Component { 43 | id: settingsComponent 44 | DeviceSettingsPage{} 45 | } 46 | Component { 47 | id: overviewComponent 48 | OverviewPage{} 49 | } 50 | Component { 51 | id: addDemoCameraComponent 52 | AddDemoCamera{} 53 | } 54 | Component { 55 | id: discoverCameraComponent 56 | DiscoverCamera{} 57 | } 58 | 59 | Component { 60 | id: aboutComponent 61 | AboutPage{} 62 | } 63 | } 64 | 65 | -------------------------------------------------------------------------------- /src/OnvifCameraViewer.qml: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2018 Casper Meijn 2 | * SPDX-License-Identifier: GPL-3.0-or-later 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | import QtMultimedia 5.9 18 | import QtQuick 2.9 19 | import QtQuick.Controls 2.3 as QQC2 20 | import net.meijn.onvifviewer 1.0 21 | 22 | Item { 23 | property OnvifDevice camera 24 | property int snapshotInterval: 1000 25 | property real aspectRatio: snapshotViewer.aspectRatio 26 | property bool loadStream: true 27 | 28 | QQC2.Label { 29 | id: loadingLabel 30 | text: i18n("Loading…") 31 | visible: !snapshotViewer.visible && !streamViewer.visible 32 | verticalAlignment: Text.AlignVCenter 33 | horizontalAlignment: Text.AlignHCenter 34 | anchors.fill: parent 35 | } 36 | 37 | OnvifSnapshotViewer { 38 | id: snapshotViewer 39 | anchors.fill: parent 40 | interval: streamViewer.visible ? -1 : streamViewer.hasError ? 0 : snapshotInterval 41 | downloader: camera ? camera.snapshotDownloader : null 42 | visible: snapshotViewer.isSnapShotAvailable && !streamViewer.visible 43 | } 44 | 45 | OnvifStreamViewer { 46 | id: streamViewer 47 | anchors.fill: parent 48 | streamUri: (loadStream && camera) ? camera.streamUri : "" 49 | visible: streamViewer.isStreamAvailable() 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /po/update_translation.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -eu 3 | # Copyright (C) 2019 Casper Meijn 4 | # 5 | # SPDX-License-Identifier: CC0-1.0 6 | 7 | BASEDIR="../src/" # root of translatable sources 8 | PROJECT="onvifviewer" # project name 9 | BUGADDR="https://gitlab.com/caspermeijn/onvifviewer/issues" # MSGID-Bugs 10 | WDIR=`pwd` # working dir 11 | DESKTOP_FILE="../desktop/net.meijn.onvifviewer.desktop" 12 | APPDATA_FILE="../desktop/net.meijn.onvifviewer.appdata.xml" 13 | 14 | 15 | echo "Preparing resource files" 16 | cd ${BASEDIR} 17 | # additional string for KAboutData 18 | echo 'i18nc("NAME OF TRANSLATORS","Your names");' >> ${WDIR}/rc.cpp 19 | echo 'i18nc("EMAIL OF TRANSLATORS","Your emails");' >> ${WDIR}/rc.cpp 20 | cd ${WDIR} 21 | echo "Done preparing rc files" 22 | 23 | 24 | echo "Extracting messages" 25 | cd ${BASEDIR} 26 | find . -name '*.cpp' -o -name '*.h' | sort > ${WDIR}/infiles.list 27 | find . -name '*.qml' | sort >> ${WDIR}/infiles.list 28 | cd ${WDIR} 29 | find . -name '*.cpp' | sort >> ${WDIR}/infiles.list 30 | xgettext --from-code=UTF-8 -C -kde -ci18n -ki18n:1 -ki18nc:1c,2 -ki18np:1,2 -ki18ncp:1c,2,3 -ktr2i18n:1 \ 31 | -kI18N_NOOP:1 -kI18N_NOOP2:1c,2 -kaliasLocale -kki18n:1 -kki18nc:1c,2 -kki18np:1,2 -kki18ncp:1c,2,3 -kN_:1 \ 32 | --package-name="${PROJECT}" \ 33 | --msgid-bugs-address="${BUGADDR}" \ 34 | --files-from=infiles.list -D ${BASEDIR} -D ${WDIR} -o messages.pot 35 | 36 | # metadata files 37 | xgettext -o desktop.pot ${DESKTOP_FILE}.in 38 | xgettext -o appdata.pot ${APPDATA_FILE}.in 39 | msgcat --use-first messages.pot desktop.pot appdata.pot > ${PROJECT}.pot 40 | 41 | sed -i '/"POT-Creation-Date:/d' ${PROJECT}.pot 42 | echo "Done extracting messages" 43 | 44 | 45 | echo "Merging translations" 46 | catalogs=`find . -name '*.po'` 47 | for cat in $catalogs; do 48 | echo $cat 49 | msgmerge -o $cat.new $cat ${PROJECT}.pot 50 | mv $cat.new $cat 51 | done 52 | echo "Done merging translations" 53 | 54 | 55 | echo "Cleaning up" 56 | cd ${WDIR} 57 | rm infiles.list 58 | rm rc.cpp 59 | rm appdata.pot desktop.pot messages.pot 60 | echo "Done" 61 | -------------------------------------------------------------------------------- /libOnvifConnect/onvifmediaprofile.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2018 Casper Meijn 2 | * SPDX-License-Identifier: GPL-3.0-or-later 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | #ifndef ONVIFMEDIAPROFILE_H 18 | #define ONVIFMEDIAPROFILE_H 19 | 20 | #include "onvifconnect_export.h" 21 | #include 22 | 23 | namespace OnvifSoapMedia 24 | { 25 | class TT__Profile; 26 | } 27 | namespace OnvifSoapMedia2 28 | { 29 | class TR2__MediaProfile; 30 | } 31 | 32 | class OnvifMediaProfilePrivate; 33 | class ONVIFCONNECT_EXPORT OnvifMediaProfile 34 | { 35 | public: 36 | OnvifMediaProfile(); 37 | OnvifMediaProfile(const OnvifMediaProfile& other); 38 | OnvifMediaProfile(const OnvifSoapMedia::TT__Profile& profile); 39 | OnvifMediaProfile(const OnvifSoapMedia2::TR2__MediaProfile& profile); 40 | ~OnvifMediaProfile(); 41 | 42 | OnvifMediaProfile& operator= (const OnvifMediaProfile& other); 43 | 44 | QString name() const; 45 | void setName(const QString& name); 46 | 47 | QString token() const; 48 | void setToken(const QString& token); 49 | 50 | bool fixed() const; 51 | void setFixed(bool fixed); 52 | 53 | QString ptzNodeToken() const; 54 | QString videoEncoding() const; 55 | long resolutionPixels() const; 56 | 57 | private: 58 | QSharedDataPointer d; 59 | }; 60 | QDebug operator<< (QDebug debug, const OnvifMediaProfile& d); 61 | 62 | #endif // ONVIFMEDIAPROFILE_H 63 | -------------------------------------------------------------------------------- /cmake/FindQtAV.cmake: -------------------------------------------------------------------------------- 1 | # - Try to find the QtAV library 2 | # 3 | # Once done this will define 4 | # 5 | # QTAV_FOUND - system has libqtav 6 | # QTAV_INCLUDE_DIRS - the libqtav include directory 7 | # QTAV_LIBRARIES - Link these to use libqtav 8 | 9 | find_package(Qt5 QUIET REQUIRED NO_MODULE COMPONENTS Core) 10 | 11 | get_target_property(qmake Qt5::qmake LOCATION) 12 | execute_process( 13 | COMMAND ${qmake} -query QT_INSTALL_HEADERS 14 | OUTPUT_VARIABLE QT_INSTALL_HEADERS 15 | OUTPUT_STRIP_TRAILING_WHITESPACE 16 | ) 17 | execute_process( 18 | COMMAND ${qmake} -query QT_INSTALL_LIBS 19 | OUTPUT_VARIABLE QT_INSTALL_LIBS 20 | OUTPUT_STRIP_TRAILING_WHITESPACE 21 | ) 22 | 23 | find_path(QTAV_INCLUDE_DIR NAMES QtAV.h 24 | HINTS ${QT_INSTALL_HEADERS} 25 | PATH_SUFFIXES QtAV 26 | ) 27 | find_library(QTAV_LIBRARY NAMES QtAV QtAV1 28 | HINTS ${QT_INSTALL_LIBS} 29 | ) 30 | 31 | find_path(QTAVWIDGETS_INCLUDE_DIR NAMES QtAVWidgets.h 32 | HINTS ${QT_INSTALL_HEADERS} 33 | PATH_SUFFIXES QtAVWidgets 34 | ) 35 | find_library(QTAVWIDGETS_LIBRARY NAMES QtAVWidgets QtAVWidgets1 36 | HINTS ${QT_INSTALL_LIBS} 37 | ) 38 | 39 | set(QTAV_INCLUDE_DIRS ${QTAV_INCLUDE_DIR} ${QTAV_INCLUDE_DIR}/..) 40 | set(QTAV_LIBRARIES ${QTAV_LIBRARY}) 41 | if(NOT QTAVWIDGETS_INCLUDE_DIR MATCHES "QTAVWIDGETS_INCLUDE_DIR-NOTFOUND") 42 | set(QTAVWIDGETS_INCLUDE_DIRS ${QTAVWIDGETS_INCLUDE_DIR} ${QTAVWIDGETS_INCLUDE_DIR}/.. ${QTAV_INCLUDE_DIRS}) 43 | endif() 44 | if(NOT QTAV_LIBRARIES MATCHES "QTAV_LIBRARIES-NOTFOUND") 45 | set(QTAVWIDGETS_LIBRARIES ${QTAVWIDGETS_LIBRARY} ${QTAV_LIBRARY}) 46 | endif() 47 | 48 | include(FindPackageHandleStandardArgs) 49 | find_package_handle_standard_args(QtAV REQUIRED_VARS QTAV_LIBRARIES QTAV_INCLUDE_DIRS) 50 | mark_as_advanced(QTAV_INCLUDE_DIRS QTAV_LIBRARIES QTAVWIDGETS_INCLUDE_DIRS QTAVWIDGETS_LIBRARIES) 51 | 52 | message("QtAV_FOUND = ${QTAV_FOUND}") 53 | message("QTAV_INCLUDE_DIRS = ${QTAV_INCLUDE_DIRS}") 54 | message("QTAV_LIBRARIES = ${QTAV_LIBRARIES}") 55 | message("QTAVWIDGETS_INCLUDE_DIRS = ${QTAVWIDGETS_INCLUDE_DIRS}") 56 | message("QTAVWIDGETS_LIBRARIES = ${QTAVWIDGETS_LIBRARIES}") 57 | -------------------------------------------------------------------------------- /src/onvifsnapshotdownloader.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2018 Casper Meijn 2 | * SPDX-License-Identifier: GPL-3.0-or-later 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | #ifndef ONVIFSNAPSHOTDOWNLOADER_H 18 | #define ONVIFSNAPSHOTDOWNLOADER_H 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | class OnvifSnapshotDownloader : public QObject 29 | { 30 | Q_OBJECT 31 | Q_PROPERTY(QPixmap snapshot READ snapshot NOTIFY snapshotChanged) 32 | Q_PROPERTY(QString error READ error NOTIFY errorChanged) 33 | public: 34 | explicit OnvifSnapshotDownloader(QObject* parent = nullptr); 35 | 36 | QPixmap snapshot() const; 37 | QString error() const; 38 | 39 | void setInterval(QObject* key, int interval); 40 | 41 | signals: 42 | void snapshotChanged(const QPixmap& snapshot); 43 | void errorChanged(const QString& error); 44 | 45 | public slots: 46 | void setSnapshotUri(const QUrl& snapshotUri); 47 | 48 | private slots: 49 | void startDownload(); 50 | void networkRequestFinished(QNetworkReply* reply); 51 | 52 | private: 53 | void setError(const QString& error); 54 | 55 | private: 56 | QUrl m_snapshotUri; 57 | QTimer m_downloadTimer; 58 | QNetworkAccessManager m_networkAccessManager; 59 | QPointer m_networkReply; 60 | QPixmap m_snapshot; 61 | QString m_error; 62 | QMap m_intervalMap; 63 | }; 64 | 65 | #endif // ONVIFSNAPSHOTDOWNLOADER_H 66 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2019 Casper Meijn 2 | # 3 | # SPDX-License-Identifier: CC0-1.0 4 | 5 | include: 6 | template: SAST.gitlab-ci.yml 7 | 8 | stages: 9 | - build 10 | - test 11 | - alpha 12 | - deploy 13 | 14 | flatpak: 15 | image: registry.gitlab.com/caspermeijn/docker-images/flatpak-kde:latest 16 | stage: build 17 | script: 18 | - flatpak-builder --repo=flatpak/repo flatpak/build --keep-build-dirs flatpak/net.meijn.onvifviewer.yaml 19 | - flatpak build-bundle flatpak/repo onvifviewer.flatpak net.meijn.onvifviewer 20 | - xvfb-run -a -s "-screen 0 1024x768x24" flatpak-builder --run flatpak/build flatpak/net.meijn.onvifviewer.yaml ninja -C .flatpak-builder/build/onvifviewer/_flatpak_build test 21 | artifacts: 22 | paths: 23 | - onvifviewer.flatpak 24 | cache: 25 | paths: 26 | - .flatpak-builder/cache 27 | 28 | fedora: 29 | image: registry.gitlab.com/caspermeijn/docker-images/fedora-build-onvifviewer:latest 30 | stage: build 31 | script: 32 | - mkdir build-onvifviewer/ 33 | - cd build-onvifviewer/ 34 | - cmake .. 35 | - make 36 | - xvfb-run -a -s "-screen 0 1024x768x24" make test 37 | - make install 38 | 39 | reuse: 40 | image: 41 | name: fsfe/reuse:latest 42 | entrypoint: [""] 43 | stage: test 44 | script: 45 | - reuse lint || echo "Always report as successful. For now this is a informational test" 46 | 47 | test-translations: 48 | image: registry.gitlab.com/caspermeijn/docker-images/fedora-build-onvifviewer:latest 49 | stage: test 50 | script: 51 | - git config diff.podiff.textconv "msgcat --no-location --sort-output" 52 | - mkdir -p .git/info && echo "*.po diff=podiff" >> .git/info/attributes && echo "*.pot diff=podiff" >> .git/info/attributes 53 | - cd po && ./update_translation.sh 54 | - mkdir build && cmake .. && cmake --build . --target fastlane-metadata 55 | # --ignore-space-change is a workaround, as --exit-code doesn't work properly without it. See http://git.661346.n2.nabble.com/git-diff-exit-code-does-not-honour-textconv-setting-tp7651075.html 56 | - git diff --ignore-space-change --exit-code 57 | artifacts: 58 | paths: 59 | - po/onvifviewer.pot 60 | - po/*.po 61 | -------------------------------------------------------------------------------- /libOnvifConnect/onvifmedia2service.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2018 Casper Meijn 2 | * SPDX-License-Identifier: GPL-3.0-or-later 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | #ifndef ONVIFMEDIA2SERVICE_H 18 | #define ONVIFMEDIA2SERVICE_H 19 | 20 | #include "onvifconnect_export.h" 21 | #include "onvifmediaprofile.h" 22 | #include 23 | 24 | class OnvifDeviceConnection; 25 | namespace OnvifSoapMedia2 26 | { 27 | class TR2__Capabilities2; 28 | } 29 | 30 | class OnvifMedia2ServicePrivate; 31 | class ONVIFCONNECT_EXPORT OnvifMedia2Service : public QObject 32 | { 33 | Q_OBJECT 34 | Q_DECLARE_PRIVATE(OnvifMedia2Service) 35 | QScopedPointer const d_ptr; 36 | public: 37 | //TODO: Move capabilities to setServiceCapabilities in private class 38 | explicit OnvifMedia2Service(const QString& endpointAddress, const OnvifSoapMedia2::TR2__Capabilities2& capabilities, OnvifDeviceConnection* parent); 39 | ~OnvifMedia2Service(); 40 | 41 | void connectToService(); 42 | void disconnectFromService(); 43 | 44 | QList getProfileList() const; 45 | 46 | void selectProfile(const OnvifMediaProfile& profile); 47 | 48 | bool supportsSnapshotUri() const; 49 | QUrl getSnapshotUri() const; 50 | QUrl getStreamUri() const; 51 | 52 | void setPreferredVideoStreamProtocol(const QString& preferredVideoStreamProtocol); 53 | 54 | signals: 55 | void profileListAvailable(const QList& profileList); 56 | void supportsSnapshotUriAvailable(bool supportsSnapshotUri); 57 | void snapshotUriAvailable(const QUrl& snapshotUri); 58 | void streamUriAvailable(const QUrl& streamUri); 59 | }; 60 | 61 | #endif // ONVIFMEDIA2SERVICE_H 62 | -------------------------------------------------------------------------------- /src/onvifsnapshotviewer.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2018 Casper Meijn 2 | * SPDX-License-Identifier: GPL-3.0-or-later 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | #ifndef ONVIFSNAPSHOTVIEWER_H 18 | #define ONVIFSNAPSHOTVIEWER_H 19 | 20 | #include "onvifsnapshotdownloader.h" 21 | #include 22 | 23 | class QPainter; 24 | 25 | class OnvifSnapshotViewer : public QQuickPaintedItem 26 | { 27 | Q_OBJECT 28 | Q_PROPERTY(OnvifSnapshotDownloader* downloader READ downloader WRITE setDownloader) 29 | Q_PROPERTY(int interval READ interval WRITE setInterval) 30 | Q_PROPERTY(qreal aspectRatio READ aspectRatio NOTIFY aspectRatioChanged) 31 | Q_PROPERTY(bool isSnapShotAvailable READ isSnapShotAvailable NOTIFY isSnapShotAvailableChanged) 32 | public: 33 | OnvifSnapshotViewer(QQuickItem* parent = Q_NULLPTR); 34 | virtual ~OnvifSnapshotViewer(); 35 | 36 | OnvifSnapshotDownloader* downloader() const; 37 | void setDownloader(OnvifSnapshotDownloader* downloader); 38 | 39 | int interval() const; 40 | void setInterval(int interval); 41 | 42 | qreal aspectRatio() const; 43 | 44 | bool isSnapShotAvailable() const; 45 | 46 | signals: 47 | void aspectRatioChanged(const qreal& aspectRatio); 48 | void isSnapShotAvailableChanged(); 49 | 50 | protected: 51 | virtual void paint(QPainter* painter) Q_DECL_OVERRIDE; 52 | 53 | private slots: 54 | void snapshotChanged(const QPixmap& snapshot); 55 | 56 | private: 57 | void updateAspectRatio(const QPixmap& pixmap); 58 | void updateAspectRatio(const qreal& aspectRatio); 59 | 60 | private: 61 | QPointer m_downloader; 62 | int m_interval = 1000; 63 | qreal m_aspectRatio = 2; 64 | }; 65 | 66 | #endif // ONVIFSNAPSHOTVIEWER_H 67 | -------------------------------------------------------------------------------- /libOnvifConnect/onvifdeviceconnection.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2018 Casper Meijn 2 | * SPDX-License-Identifier: GPL-3.0-or-later 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | #ifndef ONVIFDEVICECONNECTION_H 18 | #define ONVIFDEVICECONNECTION_H 19 | 20 | #include "onvifconnect_export.h" 21 | #include 22 | 23 | class OnvifDeviceService; 24 | class OnvifMediaService; 25 | class OnvifMedia2Service; 26 | class OnvifPtzService; 27 | 28 | class OnvifDeviceConnectionPrivate; 29 | class ONVIFCONNECT_EXPORT OnvifDeviceConnection : public QObject 30 | { 31 | Q_OBJECT 32 | Q_DECLARE_PRIVATE(OnvifDeviceConnection) 33 | friend class OnvifDeviceService; 34 | friend class OnvifDeviceServicePrivate; 35 | friend class OnvifMediaService; 36 | friend class OnvifMediaServicePrivate; 37 | friend class OnvifMedia2Service; 38 | friend class OnvifMedia2ServicePrivate; 39 | friend class OnvifPtzService; 40 | friend class OnvifPtzServicePrivate; 41 | QScopedPointer const d_ptr; 42 | public: 43 | explicit OnvifDeviceConnection(QObject* parent = nullptr); 44 | ~OnvifDeviceConnection(); 45 | 46 | void setHostname(const QString& hostname); 47 | void setCredentials(const QString& username, const QString& password); 48 | 49 | QString errorString() const; 50 | 51 | void connectToDevice(); 52 | void disconnectFromDevice(); 53 | 54 | OnvifDeviceService* getDeviceService() const; 55 | OnvifMediaService* getMediaService() const; 56 | OnvifMedia2Service* getMedia2Service() const; 57 | OnvifPtzService* getPtzService() const; 58 | 59 | signals: 60 | void servicesAvailable(); 61 | void errorStringChanged(const QString& errorString); 62 | }; 63 | 64 | #endif // ONVIFDEVICECONNECTION_H 65 | -------------------------------------------------------------------------------- /fastlane/prepare_metadata_for_alpha.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright (C) 2019 Casper Meijn 4 | # SPDX-License-Identifier: GPL-3.0-or-later 5 | # 6 | # This program is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with this program. If not, see . 18 | 19 | import xml.etree.ElementTree as ET 20 | import argparse 21 | from pathlib import Path 22 | import os 23 | import shutil 24 | 25 | parser = argparse.ArgumentParser(description='Convert appstream metadata to fastlane metadata.') 26 | parser.add_argument('--manifest', required=True, help='path to the Android manifest file') 27 | parser.add_argument('--fastlane', required=True, help='path to the fastlane metadata directory') 28 | args = parser.parse_args() 29 | 30 | fastlane_path = Path(args.fastlane) 31 | fastlane_path.mkdir(0o755, True, True) 32 | 33 | tree = ET.parse(args.manifest) 34 | root = tree.getroot() 35 | 36 | version_code = root.attrib.get('{http://schemas.android.com/apk/res/android}versionCode') 37 | if not version_code: 38 | sys.exit('version code not found in manifest') 39 | 40 | changelog_dir = fastlane_path.joinpath('android/en-GB/changelogs/') 41 | if not changelog_dir.exists(): 42 | sys.exit('no changelog dir found in metadata directory') 43 | 44 | current_changelog_path = changelog_dir.joinpath(version_code + ".txt") 45 | 46 | best_changelog_path = "" 47 | best_changelog_number = 0 48 | for entry in os.scandir(str(changelog_dir.resolve())): 49 | if entry.is_file(): 50 | entry_number = int(entry.name.split('.')[0]) 51 | if entry_number > best_changelog_number: 52 | best_changelog_number = entry_number 53 | best_changelog_path = changelog_dir.joinpath(entry.name) 54 | 55 | 56 | print("Copying", best_changelog_path, "to", current_changelog_path) 57 | try: 58 | shutil.copyfile(str(best_changelog_path), str(current_changelog_path)) 59 | except (shutil.SameFileError): 60 | pass 61 | 62 | -------------------------------------------------------------------------------- /libOnvifConnect/onvifmediaservice.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2018 Casper Meijn 2 | * SPDX-License-Identifier: GPL-3.0-or-later 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | #ifndef ONVIFMEDIASERVICE_H 18 | #define ONVIFMEDIASERVICE_H 19 | 20 | #include "onvifconnect_export.h" 21 | #include "onvifmediaprofile.h" 22 | #include 23 | 24 | class OnvifDeviceConnection; 25 | namespace OnvifSoapDevicemgmt 26 | { 27 | class TT__MediaCapabilities; 28 | } 29 | namespace OnvifSoapMedia 30 | { 31 | class TRT__Capabilities; 32 | } 33 | 34 | class OnvifMediaServicePrivate; 35 | class ONVIFCONNECT_EXPORT OnvifMediaService : public QObject 36 | { 37 | Q_OBJECT 38 | Q_DECLARE_PRIVATE(OnvifMediaService) 39 | QScopedPointer const d_ptr; 40 | public: 41 | explicit OnvifMediaService(const QString& endpointAddress, OnvifDeviceConnection* parent); 42 | ~OnvifMediaService(); 43 | 44 | void connectToService(); 45 | void disconnectFromService(); 46 | 47 | QList getProfileList() const; 48 | 49 | void selectProfile(const OnvifMediaProfile& profile); 50 | 51 | bool supportsSnapshotUri() const; 52 | QUrl getSnapshotUri() const; 53 | QUrl getStreamUri() const; 54 | 55 | //TODO: Move setServiceCapabilities to private class 56 | void setServiceCapabilities(const OnvifSoapMedia::TRT__Capabilities& capabilities); 57 | void setServiceCapabilities(const OnvifSoapDevicemgmt::TT__MediaCapabilities& capabilities); 58 | 59 | void setPreferredVideoStreamProtocol(const QString& preferredVideoStreamProtocol); 60 | 61 | signals: 62 | void profileListAvailable(const QList& profileList); 63 | void supportsSnapshotUriAvailable(bool supportsSnapshotUri); 64 | void snapshotUriAvailable(const QUrl& snapshotUri); 65 | void streamUriAvailable(const QUrl& streamUri); 66 | }; 67 | 68 | #endif // ONVIFMEDIASERVICE_H 69 | -------------------------------------------------------------------------------- /libOnvifConnect/onvifdeviceconnection_p.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2018 Casper Meijn 2 | * SPDX-License-Identifier: GPL-3.0-or-later 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef ONVIFDEVICECONNECTION_P_H 19 | #define ONVIFDEVICECONNECTION_P_H 20 | 21 | #include "onvifdeviceconnection.h" 22 | #include "wsdl_devicemgmt.h" 23 | 24 | class OnvifDeviceConnectionPrivate 25 | { 26 | Q_DISABLE_COPY(OnvifDeviceConnectionPrivate) 27 | Q_DECLARE_PUBLIC(OnvifDeviceConnection) 28 | private: 29 | OnvifDeviceConnectionPrivate(OnvifDeviceConnection* connection); 30 | 31 | OnvifDeviceConnection* const q_ptr; 32 | 33 | OnvifSoapDevicemgmt::DeviceBindingService soapService; 34 | OnvifDeviceService* deviceService = nullptr; 35 | OnvifMediaService* mediaService = nullptr; 36 | OnvifMedia2Service* media2Service = nullptr; 37 | OnvifPtzService* ptzService = nullptr; 38 | 39 | QString hostname; 40 | QString username; 41 | QString password; 42 | 43 | QString errorString; 44 | 45 | bool isUsernameTokenSupported = false; 46 | bool isHttpDigestSupported = false; 47 | 48 | bool isGetServicesFinished = false; 49 | bool isGetCapabilitiesFinished = false; 50 | 51 | static const QString c_baseEndpointURI; 52 | 53 | void getServicesDone(const OnvifSoapDevicemgmt::TDS__GetServicesResponse& parameters); 54 | void getServicesError(const KDSoapMessage& fault); 55 | void getCapabilitiesDone(const OnvifSoapDevicemgmt::TDS__GetCapabilitiesResponse& parameters); 56 | void getCapabilitiesError(const KDSoapMessage& fault); 57 | 58 | void checkServicesAvailable(); 59 | 60 | public: 61 | void updateUrlHost(QUrl* url); 62 | void updateSoapCredentials(KDSoapClientInterface* clientInterface); 63 | void updateUrlCredentials(QUrl* url); 64 | void handleSoapError(const KDSoapMessage& fault, const QString& location); 65 | }; 66 | 67 | #endif // ONVIFDEVICECONNECTION_P_H 68 | -------------------------------------------------------------------------------- /src/onvifdevicediscover.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2019 Casper Meijn 2 | * SPDX-License-Identifier: GPL-3.0-or-later 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | #ifndef ONVIFDEVICEDISCOVER_H 18 | #define ONVIFDEVICEDISCOVER_H 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | class WSDiscoveryClient; 26 | class WSDiscoveryProbeJob; 27 | class WSDiscoveryTargetService; 28 | 29 | class OnvifDeviceDiscoverMatch : public QObject 30 | { 31 | Q_OBJECT 32 | Q_PROPERTY(QString name READ getName CONSTANT) 33 | Q_PROPERTY(QString hardware READ getHardware CONSTANT) 34 | Q_PROPERTY(QString endpoint READ getEndpoint CONSTANT) 35 | Q_PROPERTY(QUrl xAddr READ getXAddr CONSTANT) 36 | Q_PROPERTY(QString host READ getHost CONSTANT) 37 | public: 38 | QString getName() const; 39 | QString getHardware() const; 40 | QString getEndpoint() const; 41 | QUrl getXAddr() const; 42 | QString getHost() const; 43 | 44 | protected: 45 | QString m_name; 46 | QString m_hardware; 47 | QString m_endpoint; 48 | QUrl m_xAddr; 49 | QDateTime m_lastSeen; 50 | 51 | friend class OnvifDeviceDiscover; 52 | }; 53 | 54 | class OnvifDeviceDiscover : public QObject 55 | { 56 | Q_OBJECT 57 | Q_PROPERTY(bool isAvailable READ isAvailable CONSTANT) 58 | Q_PROPERTY(QObjectList matchList READ matchList NOTIFY matchListChanged) 59 | public: 60 | explicit OnvifDeviceDiscover(QObject* parent = nullptr); 61 | bool isAvailable(); 62 | QObjectList matchList() const; 63 | 64 | signals: 65 | void matchListChanged(QObjectList matchMap); 66 | 67 | public slots: 68 | void start(); 69 | 70 | private slots: 71 | void matchReceived(const WSDiscoveryTargetService& matchedService); 72 | 73 | private: 74 | WSDiscoveryClient* m_client; 75 | WSDiscoveryProbeJob* m_probeJob; 76 | QMap m_matchMap; 77 | }; 78 | 79 | #endif // ONVIFDEVICEDISCOVER_H 80 | -------------------------------------------------------------------------------- /src/AddDemoCamera.qml: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2018 Casper Meijn 2 | * SPDX-License-Identifier: GPL-3.0-or-later 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | import net.meijn.onvifviewer 1.0 18 | import org.kde.kirigami 2.6 as Kirigami 19 | import QtQuick 2.9 20 | import QtQuick.Controls 2.3 21 | 22 | Kirigami.ScrollablePage { 23 | title: i18n("Add demo camera") 24 | objectName: "addDemoCameraPage" 25 | 26 | ListModel { 27 | id: demoCameraModel 28 | ListElement { 29 | deviceName: "Demo Norway" 30 | hostName: "79.160.18.23:10000" 31 | userName: "" 32 | password: "" 33 | preferredVideoStreamProtocol: "RtspOverHttp" 34 | } 35 | ListElement { 36 | deviceName: "Demo Zurich" 37 | hostName: "213.173.165.16:90" 38 | userName: "" 39 | password: "" 40 | } 41 | ListElement { 42 | deviceName: "Demo frontdoor" 43 | hostName: "84.171.95.10:50001" 44 | userName: "service" 45 | password: "service" 46 | } 47 | } 48 | 49 | ListView { 50 | anchors.fill: parent 51 | model: demoCameraModel 52 | delegate: Button { 53 | text: deviceName 54 | onClicked: { 55 | selectedIndex = deviceManager.appendDevice() 56 | var newDevice = deviceManager.at(selectedIndex) 57 | newDevice.deviceName = deviceName; 58 | newDevice.hostName = hostName; 59 | newDevice.userName = userName ? userName : ""; 60 | newDevice.password = password ? password : ""; 61 | newDevice.preferredVideoStreamProtocol = preferredVideoStreamProtocol ? preferredVideoStreamProtocol : ""; 62 | newDevice.connectToDevice(); 63 | deviceManager.saveDevices() 64 | 65 | pageStack.pop(); 66 | pageStack.push(deviceViewerComponent); 67 | } 68 | width: parent.width 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /libOnvifConnect/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2018 Casper Meijn 2 | # SPDX-License-Identifier: GPL-3.0-or-later 3 | # 4 | # This program is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | cmake_minimum_required(VERSION 3.0) 18 | cmake_policy(SET CMP0063 NEW) 19 | 20 | include(GenerateExportHeader) 21 | 22 | include(ECMGenerateHeaders) 23 | 24 | # if (BUILD_TESTING) 25 | # add_subdirectory(autotests) 26 | # add_subdirectory(tests) 27 | # endif() 28 | 29 | set(GLOBAL_KSWSDL2CPP_OPTION) 30 | if(KDSoap_VERSION VERSION_GREATER_EQUAL 1.8.0) 31 | get_filename_component(KDWSDL_IMPORT_PATH ../3rdparty/wsdl/ ABSOLUTE) 32 | set(GLOBAL_KSWSDL2CPP_OPTION -import-path ${KDWSDL_IMPORT_PATH} -use-local-files-only) 33 | endif() 34 | 35 | set(KSWSDL2CPP_OPTION -namespace OnvifSoapDevicemgmt ${GLOBAL_KSWSDL2CPP_OPTION}) 36 | KDSOAP_GENERATE_WSDL(libOnvifConnect_WSDL ../3rdparty/wsdl/www.onvif.org/ver10/device/wsdl/devicemgmt.wsdl) 37 | set(KSWSDL2CPP_OPTION -namespace OnvifSoapMedia ${GLOBAL_KSWSDL2CPP_OPTION}) 38 | KDSOAP_GENERATE_WSDL(libOnvifConnect_WSDL ../3rdparty/wsdl/www.onvif.org/ver10/media/wsdl/media.wsdl) 39 | set(KSWSDL2CPP_OPTION -namespace OnvifSoapMedia2 ${GLOBAL_KSWSDL2CPP_OPTION}) 40 | #TODO: Fix the media2.wsdl file, as this is not the original file path 41 | KDSOAP_GENERATE_WSDL(libOnvifConnect_WSDL ../3rdparty/wsdl/www.onvif.org/ver20/media/wsdl/media2.wsdl) 42 | set(KSWSDL2CPP_OPTION -namespace OnvifSoapPtz ${GLOBAL_KSWSDL2CPP_OPTION}) 43 | KDSOAP_GENERATE_WSDL(libOnvifConnect_WSDL ../3rdparty/wsdl/www.onvif.org/ver20/ptz/wsdl/ptz.wsdl) 44 | 45 | set(libOnvifConnect_SRCS 46 | onvifdeviceservice.cpp 47 | onvifmediaservice.cpp 48 | onvifdeviceconnection.cpp 49 | onvifmedia2service.cpp 50 | onvifptzservice.cpp 51 | onvifdeviceinformation.cpp 52 | onvifmediaprofile.cpp 53 | ) 54 | 55 | add_library(libOnvifConnect STATIC ${libOnvifConnect_SRCS} ${libOnvifConnect_WSDL}) 56 | generate_export_header(libOnvifConnect BASE_NAME OnvifConnect) 57 | 58 | target_link_libraries(libOnvifConnect 59 | PUBLIC 60 | Qt5::Core 61 | KDSoap::kdsoap 62 | PRIVATE 63 | Qt5::Network 64 | ) 65 | -------------------------------------------------------------------------------- /libOnvifConnect/onvifptzservice.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2018 Casper Meijn 2 | * SPDX-License-Identifier: GPL-3.0-or-later 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | #ifndef ONVIFPTZSERVICE_H 18 | #define ONVIFPTZSERVICE_H 19 | 20 | #include "onvifconnect_export.h" 21 | #include 22 | 23 | class OnvifDeviceConnection; 24 | class OnvifMediaProfile; 25 | namespace OnvifSoapDevicemgmt 26 | { 27 | class TT__PTZCapabilities; 28 | } 29 | namespace OnvifSoapPtz 30 | { 31 | class TPTZ__Capabilities; 32 | } 33 | 34 | class OnvifPtzServicePrivate; 35 | class ONVIFCONNECT_EXPORT OnvifPtzService : public QObject 36 | { 37 | Q_OBJECT 38 | Q_DECLARE_PRIVATE(OnvifPtzService) 39 | QScopedPointer const d_ptr; 40 | public: 41 | explicit OnvifPtzService(const QString& endpointAddress, OnvifDeviceConnection* parent); 42 | ~OnvifPtzService(); 43 | 44 | void connectToService(); 45 | void disconnectFromService(); 46 | 47 | //TODO: Move setServiceCapabilities to private class 48 | void setServiceCapabilities(const OnvifSoapPtz::TPTZ__Capabilities& capabilities); 49 | void setServiceCapabilities(const OnvifSoapDevicemgmt::TT__PTZCapabilities& capabilities); 50 | 51 | void absoluteMove(const OnvifMediaProfile& profile, float xFraction, float yFraction); 52 | 53 | bool isRelativeMoveSupported(const OnvifMediaProfile& profile) const; 54 | void relativeMove(const OnvifMediaProfile& profile, float xFraction, float yFraction); 55 | 56 | bool isContinuousMoveSupported(const OnvifMediaProfile& profile) const; 57 | void continuousMove(const OnvifMediaProfile& profile, float xFraction, float yFraction); 58 | 59 | bool isRelativeZoomSupported(const OnvifMediaProfile& profile) const; 60 | void relativeZoom(const OnvifMediaProfile& profile, float zoomFraction); 61 | 62 | bool isHomeSupported(const OnvifMediaProfile& profile) const; 63 | void goToHome(const OnvifMediaProfile& profile); 64 | void saveHomePosition(const OnvifMediaProfile& profile); 65 | 66 | void stopMovement(const OnvifMediaProfile& profile); 67 | }; 68 | 69 | 70 | #endif // ONVIFPTZSERVICE_H 71 | -------------------------------------------------------------------------------- /libOnvifConnect/onvifdeviceinformation.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2018 Casper Meijn 2 | * SPDX-License-Identifier: GPL-3.0-or-later 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | #ifndef ONVIFDEVICEINFORMATION_H 18 | #define ONVIFDEVICEINFORMATION_H 19 | 20 | #include "onvifconnect_export.h" 21 | #include 22 | #include 23 | 24 | namespace OnvifSoapDevicemgmt 25 | { 26 | class TDS__GetDeviceInformationResponse; 27 | } 28 | 29 | class OnvifDeviceInformationPrivate; 30 | class ONVIFCONNECT_EXPORT OnvifDeviceInformation : public QObject 31 | { 32 | Q_OBJECT 33 | Q_PROPERTY(QString manufacturer READ manufacturer NOTIFY manufacturerChanged) 34 | Q_PROPERTY(QString model READ model NOTIFY modelChanged) 35 | Q_PROPERTY(QString firmwareVersion READ firmwareVersion NOTIFY firmwareVersionChanged) 36 | Q_PROPERTY(QString serialNumber READ serialNumber NOTIFY serialNumberChanged) 37 | Q_PROPERTY(QString hardwareId READ hardwareId NOTIFY hardwareIdChanged) 38 | public: 39 | OnvifDeviceInformation(QObject* parent = nullptr); 40 | OnvifDeviceInformation(const OnvifDeviceInformation& other, QObject* parent = nullptr); 41 | OnvifDeviceInformation(const OnvifSoapDevicemgmt::TDS__GetDeviceInformationResponse& deviceInformationResponse, QObject* parent = nullptr); 42 | ~OnvifDeviceInformation(); 43 | 44 | OnvifDeviceInformation& operator= (const OnvifDeviceInformation& other); 45 | 46 | QString manufacturer() const; 47 | QString model() const; 48 | QString firmwareVersion() const; 49 | QString serialNumber() const; 50 | QString hardwareId() const; 51 | 52 | signals: 53 | void manufacturerChanged(const QString& manufacturer); 54 | void modelChanged(const QString& model); 55 | void firmwareVersionChanged(const QString& firmwareVersion); 56 | void serialNumberChanged(const QString& serialNumber); 57 | void hardwareIdChanged(const QString& hardwareId); 58 | 59 | private: 60 | QSharedDataPointer d; 61 | }; 62 | 63 | QDebug operator<< (QDebug debug, const OnvifDeviceInformation& d); 64 | 65 | #endif // ONVIFDEVICEINFORMATION_H 66 | -------------------------------------------------------------------------------- /desktop/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2018-2019 Casper Meijn 2 | # SPDX-License-Identifier: GPL-3.0-or-later 3 | # 4 | # This program is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | cmake_minimum_required(VERSION 3.7) 18 | 19 | # desktop file 20 | set(_desktopTemplate net.meijn.onvifviewer.desktop.in) 21 | set(_desktopFile ${CMAKE_CURRENT_BINARY_DIR}/net.meijn.onvifviewer.desktop) 22 | add_custom_command( 23 | OUTPUT ${_desktopFile} 24 | COMMAND ${GETTEXT_MSGFMT_EXECUTABLE} --check --use-fuzzy --desktop --template ${_desktopTemplate} -o ${_desktopFile} -d ../po/ 25 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 26 | DEPENDS ${_desktopTemplate} translations) 27 | add_custom_target(desktop-file ALL DEPENDS ${_desktopFile}) 28 | install(FILES ${_desktopFile} DESTINATION ${KDE_INSTALL_APPDIR}) 29 | 30 | find_program(DESKTOP_FILE_VALIDATE_EXECUTABLE desktop-file-validate) 31 | if(DESKTOP_FILE_VALIDATE_EXECUTABLE) 32 | add_test(NAME validate-desktop-file COMMAND ${DESKTOP_FILE_VALIDATE_EXECUTABLE} --warn-kde ${_desktopFile}) 33 | endif() 34 | 35 | # appstream metadata 36 | set(_appDataTemplate net.meijn.onvifviewer.appdata.xml.in) 37 | set(_appDataFile ${CMAKE_CURRENT_BINARY_DIR}/net.meijn.onvifviewer.appdata.xml) 38 | add_custom_command( 39 | OUTPUT ${_appDataFile} 40 | COMMAND ${GETTEXT_MSGFMT_EXECUTABLE} --check --use-fuzzy --xml --template ${_appDataTemplate} -o ${_appDataFile} -d ../po/ 41 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 42 | DEPENDS ${_appDataTemplate} translations) 43 | add_custom_target(app-data ALL DEPENDS ${_appDataFile}) 44 | install(FILES ${_appDataFile} DESTINATION ${KDE_INSTALL_METAINFODIR}) 45 | 46 | find_program(APPSTREAM_UTIL_EXECUTABLE appstream-util) 47 | if(APPSTREAM_UTIL_EXECUTABLE) 48 | add_test(NAME validate-appdata COMMAND ${APPSTREAM_UTIL_EXECUTABLE} validate-strict ${_appDataFile}) 49 | endif() 50 | 51 | # icons 52 | install(FILES ApplicationIcon.svg DESTINATION ${KDE_INSTALL_ICONDIR}/hicolor/scalable/apps RENAME net.meijn.onvifviewer.svg) 53 | foreach(_iconSize 16 22 24 32 48 64 128 256) 54 | install(FILES ApplicationIcon-${_iconSize}.png DESTINATION ${KDE_INSTALL_ICONDIR}/hicolor/${_iconSize}x${_iconSize}/apps RENAME net.meijn.onvifviewer.png) 55 | endforeach() 56 | -------------------------------------------------------------------------------- /src/DiscoverCamera.qml: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2018-2019 Casper Meijn 2 | * SPDX-License-Identifier: GPL-3.0-or-later 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | import net.meijn.onvifviewer 1.0 18 | import org.kde.kirigami 2.6 as Kirigami 19 | import QtQuick 2.9 20 | import QtQuick.Controls 2.3 as Controls 21 | import QtQuick.Layouts 1.3 22 | 23 | Kirigami.ScrollablePage { 24 | id: pageDiscoverCamera 25 | title: i18n("Discover camera") 26 | objectName: "discoverCameraPage" 27 | 28 | ColumnLayout { 29 | width: pageDiscoverCamera.width 30 | height: pageDiscoverCamera.height 31 | 32 | Controls.Label { 33 | text: i18n("No camera discovered in the local network.") 34 | visible: deviceDiscover.matchList.length === 0 35 | wrapMode: Text.WordWrap 36 | Layout.fillWidth: true 37 | Layout.fillHeight: true 38 | } 39 | 40 | Controls.Label { 41 | text: i18n("Click on a discovered camera to add it:") 42 | visible: deviceDiscover.matchList.length !== 0 43 | wrapMode: Text.WordWrap 44 | Layout.fillWidth: true 45 | } 46 | 47 | ListView { 48 | visible: deviceDiscover.matchList.length !== 0 49 | Layout.fillWidth: true 50 | Layout.fillHeight: true 51 | model: deviceDiscover.matchList 52 | delegate: Kirigami.BasicListItem { 53 | icon: "camera-video" 54 | label: modelData.name + "/" + modelData.hardware 55 | onClicked: { 56 | selectedIndex = deviceManager.appendDevice() 57 | var newDevice = deviceManager.at(selectedIndex) 58 | newDevice.deviceName = modelData.name; 59 | console.log(modelData.xAddr) 60 | newDevice.hostName = modelData.host; 61 | newDevice.connectToDevice(); 62 | deviceManager.saveDevices() 63 | 64 | pageStack.pop(); 65 | pageStack.push(settingsComponent); 66 | } 67 | width: parent.width 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/onvifsnapshotdownloader.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2018 Casper Meijn 2 | * SPDX-License-Identifier: GPL-3.0-or-later 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | #include "onvifsnapshotdownloader.h" 18 | 19 | OnvifSnapshotDownloader::OnvifSnapshotDownloader(QObject* parent) : QObject(parent) 20 | { 21 | m_downloadTimer.setInterval(1000); 22 | m_downloadTimer.setSingleShot(true); 23 | connect(&m_downloadTimer, &QTimer::timeout, this, &OnvifSnapshotDownloader::startDownload); 24 | connect(&m_networkAccessManager, &QNetworkAccessManager::finished, this, &OnvifSnapshotDownloader::networkRequestFinished); 25 | } 26 | 27 | void OnvifSnapshotDownloader::setSnapshotUri(const QUrl& snapshotUri) 28 | { 29 | m_snapshotUri = snapshotUri; 30 | startDownload(); 31 | } 32 | 33 | void OnvifSnapshotDownloader::startDownload() 34 | { 35 | if (m_networkReply) { 36 | m_networkReply->abort(); 37 | } 38 | QNetworkRequest request(m_snapshotUri); 39 | m_networkReply = m_networkAccessManager.get(request); 40 | } 41 | 42 | void OnvifSnapshotDownloader::networkRequestFinished(QNetworkReply* reply) 43 | { 44 | //TODO: detect abort 45 | if (reply->error() == QNetworkReply::NoError) { 46 | auto downloadedData = reply->readAll(); 47 | bool result = m_snapshot.loadFromData(downloadedData); 48 | if (!result) { 49 | setError("Failed to load snapshot"); 50 | } 51 | emit snapshotChanged(m_snapshot); 52 | } else { 53 | setError(reply->errorString()); 54 | } 55 | reply->deleteLater(); 56 | m_downloadTimer.start(); 57 | } 58 | 59 | QString OnvifSnapshotDownloader::error() const 60 | { 61 | return m_error; 62 | } 63 | 64 | void OnvifSnapshotDownloader::setInterval(QObject* key, int interval) 65 | { 66 | if (interval != -1) { 67 | m_intervalMap.insert(key, interval); 68 | } else { 69 | m_intervalMap.remove(key); 70 | } 71 | int minInterval = std::numeric_limits::max(); 72 | for (auto interval : qAsConst(m_intervalMap)) { 73 | minInterval = qMin(interval, minInterval); 74 | } 75 | if (m_downloadTimer.interval() != minInterval) { 76 | m_downloadTimer.setInterval(minInterval); 77 | } 78 | } 79 | 80 | void OnvifSnapshotDownloader::setError(const QString& error) 81 | { 82 | m_error = error; 83 | emit errorChanged(m_error); 84 | } 85 | 86 | QPixmap OnvifSnapshotDownloader::snapshot() const 87 | { 88 | return m_snapshot; 89 | } 90 | -------------------------------------------------------------------------------- /src/onvifsnapshotviewer.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2018 Casper Meijn 2 | * SPDX-License-Identifier: GPL-3.0-or-later 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | #include "onvifsnapshotviewer.h" 18 | 19 | #include 20 | #include 21 | 22 | OnvifSnapshotViewer::OnvifSnapshotViewer(QQuickItem* parent) : 23 | QQuickPaintedItem(parent) 24 | { 25 | } 26 | 27 | OnvifSnapshotViewer::~OnvifSnapshotViewer() 28 | { 29 | if (m_downloader) { 30 | m_downloader->setInterval(this, -1); 31 | } 32 | } 33 | 34 | void OnvifSnapshotViewer::paint(QPainter* painter) 35 | { 36 | if (m_downloader) { 37 | const QPixmap& snapshot = m_downloader->snapshot(); 38 | int heightPixmap = (int)(width() / aspectRatio()); 39 | int y = ((int)height() - heightPixmap) / 2; 40 | painter->drawPixmap(0, y, (int)width(), heightPixmap, snapshot); 41 | } 42 | } 43 | 44 | void OnvifSnapshotViewer::snapshotChanged(const QPixmap& snapshot) 45 | { 46 | update(); 47 | updateAspectRatio(snapshot); 48 | emit isSnapShotAvailableChanged(); 49 | } 50 | 51 | qreal OnvifSnapshotViewer::aspectRatio() const 52 | { 53 | return m_aspectRatio; 54 | } 55 | 56 | void OnvifSnapshotViewer::updateAspectRatio(const QPixmap& pixmap) 57 | { 58 | qreal height = pixmap.height(); 59 | qreal width = pixmap.width(); 60 | updateAspectRatio(width / height); 61 | } 62 | 63 | void OnvifSnapshotViewer::updateAspectRatio(const qreal& aspectRatio) 64 | { 65 | if (m_aspectRatio != aspectRatio) { 66 | m_aspectRatio = aspectRatio; 67 | emit aspectRatioChanged(m_aspectRatio); 68 | } 69 | } 70 | 71 | bool OnvifSnapshotViewer::isSnapShotAvailable() const 72 | { 73 | return !m_downloader->snapshot().isNull(); 74 | } 75 | 76 | int OnvifSnapshotViewer::interval() const 77 | { 78 | return m_interval; 79 | } 80 | 81 | void OnvifSnapshotViewer::setInterval(int interval) 82 | { 83 | m_interval = interval; 84 | if (m_downloader) { 85 | m_downloader->setInterval(this, m_interval); 86 | } 87 | } 88 | 89 | OnvifSnapshotDownloader* OnvifSnapshotViewer::downloader() const 90 | { 91 | return m_downloader; 92 | } 93 | 94 | void OnvifSnapshotViewer::setDownloader(OnvifSnapshotDownloader* downloader) 95 | { 96 | if (m_downloader) { 97 | m_downloader->setInterval(this, -1); 98 | disconnect(m_downloader, nullptr, this, nullptr); 99 | } 100 | m_downloader = downloader; 101 | if (m_downloader) { 102 | if (!m_downloader->snapshot().isNull()) { 103 | snapshotChanged(m_downloader->snapshot()); 104 | } 105 | connect(m_downloader, &OnvifSnapshotDownloader::snapshotChanged, this, &OnvifSnapshotViewer::snapshotChanged); 106 | m_downloader->setInterval(this, m_interval); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /libOnvifConnect/onvifdeviceservice.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2018 Casper Meijn 2 | * SPDX-License-Identifier: GPL-3.0-or-later 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | #include "onvifdeviceconnection_p.h" 18 | #include "onvifdeviceservice.h" 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include "wsdl_devicemgmt.h" 25 | 26 | using namespace OnvifSoapDevicemgmt; 27 | 28 | #define Q_FUNC_INFO_AS_STRING (QString(static_cast(Q_FUNC_INFO))) 29 | 30 | class OnvifDeviceServicePrivate 31 | { 32 | Q_DISABLE_COPY(OnvifDeviceServicePrivate) 33 | Q_DECLARE_PUBLIC(OnvifDeviceService) 34 | public: 35 | OnvifDeviceServicePrivate(OnvifDeviceService* service, OnvifDeviceConnection* device) : 36 | q_ptr(service), 37 | device(device) 38 | {;} 39 | 40 | OnvifDeviceService* const q_ptr; 41 | OnvifDeviceConnection* device; 42 | DeviceBindingService soapService; 43 | OnvifDeviceInformation deviceInformation; 44 | 45 | void getDeviceInformationDone(const OnvifSoapDevicemgmt::TDS__GetDeviceInformationResponse& parameters); 46 | void getDeviceInformationError(const KDSoapMessage& fault); 47 | }; 48 | 49 | OnvifDeviceService::OnvifDeviceService(const QString& soapEndpoint, OnvifDeviceConnection* parent) : 50 | QObject(parent), 51 | d_ptr(new OnvifDeviceServicePrivate(this, parent)) 52 | { 53 | Q_D(OnvifDeviceService); 54 | d->soapService.setEndPoint(soapEndpoint); 55 | 56 | connect(&d->soapService, &DeviceBindingService::getDeviceInformationDone, 57 | [d](const OnvifSoapDevicemgmt::TDS__GetDeviceInformationResponse & parameters) { 58 | d->getDeviceInformationDone(parameters); 59 | }); 60 | connect(&d->soapService, &DeviceBindingService::getDeviceInformationError, 61 | [d](const KDSoapMessage & fault) { 62 | d->getDeviceInformationError(fault); 63 | }); 64 | } 65 | 66 | OnvifDeviceService::~OnvifDeviceService() = default; 67 | 68 | void OnvifDeviceService::connectToService() 69 | { 70 | Q_D(OnvifDeviceService); 71 | d->device->d_ptr->updateSoapCredentials(d->soapService.clientInterface()); 72 | d->soapService.asyncGetDeviceInformation(); 73 | } 74 | 75 | void OnvifDeviceService::disconnectFromService() 76 | { 77 | Q_D(OnvifDeviceService); 78 | d->deviceInformation = OnvifDeviceInformation(); 79 | } 80 | 81 | OnvifDeviceInformation OnvifDeviceService::getDeviceInformation() 82 | { 83 | Q_D(OnvifDeviceService); 84 | return d->deviceInformation; 85 | } 86 | 87 | void OnvifDeviceServicePrivate::getDeviceInformationDone(const TDS__GetDeviceInformationResponse& parameters) 88 | { 89 | Q_Q(OnvifDeviceService); 90 | deviceInformation = OnvifDeviceInformation(parameters); 91 | emit q->deviceInformationAvailable(deviceInformation); 92 | } 93 | 94 | void OnvifDeviceServicePrivate::getDeviceInformationError(const KDSoapMessage& fault) 95 | { 96 | device->d_ptr->handleSoapError(fault, Q_FUNC_INFO_AS_STRING); 97 | } 98 | -------------------------------------------------------------------------------- /libOnvifConnect/onvifdeviceinformation.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2018 Casper Meijn 2 | * SPDX-License-Identifier: GPL-3.0-or-later 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | #include "onvifdeviceinformation.h" 18 | 19 | #include 20 | #include "wsdl_devicemgmt.h" 21 | 22 | using namespace OnvifSoapDevicemgmt; 23 | 24 | class OnvifDeviceInformationPrivate : public QSharedData 25 | { 26 | public: 27 | OnvifDeviceInformationPrivate() 28 | {;} 29 | 30 | OnvifDeviceInformationPrivate(const TDS__GetDeviceInformationResponse& deviceInformationResponse) : 31 | manufacturer(deviceInformationResponse.manufacturer()), 32 | model(deviceInformationResponse.model()), 33 | firmwareVersion(deviceInformationResponse.firmwareVersion()), 34 | serialNumber(deviceInformationResponse.serialNumber()), 35 | hardwareId(deviceInformationResponse.hardwareId()) 36 | { 37 | } 38 | 39 | QString manufacturer; 40 | QString model; 41 | QString firmwareVersion; 42 | QString serialNumber; 43 | QString hardwareId; 44 | }; 45 | 46 | OnvifDeviceInformation::OnvifDeviceInformation(QObject* parent) : 47 | QObject(parent), 48 | d(new OnvifDeviceInformationPrivate()) 49 | { 50 | } 51 | 52 | OnvifDeviceInformation::OnvifDeviceInformation(const OnvifDeviceInformation& other, QObject* parent) : 53 | QObject(parent), 54 | d(other.d) 55 | { 56 | } 57 | 58 | OnvifDeviceInformation::OnvifDeviceInformation(const TDS__GetDeviceInformationResponse& profile, QObject* parent) : 59 | QObject(parent), 60 | d(new OnvifDeviceInformationPrivate(profile)) 61 | { 62 | } 63 | 64 | OnvifDeviceInformation::~OnvifDeviceInformation() = default; 65 | 66 | OnvifDeviceInformation& OnvifDeviceInformation::operator= (const OnvifDeviceInformation& other) 67 | { 68 | if (this != &other) { 69 | OnvifDeviceInformation copy(other); 70 | d.swap(copy.d); 71 | } 72 | return *this; 73 | } 74 | 75 | QString OnvifDeviceInformation::manufacturer() const 76 | { 77 | return d->manufacturer; 78 | } 79 | 80 | QString OnvifDeviceInformation::model() const 81 | { 82 | return d->model; 83 | } 84 | 85 | QString OnvifDeviceInformation::firmwareVersion() const 86 | { 87 | return d->firmwareVersion; 88 | } 89 | 90 | QString OnvifDeviceInformation::serialNumber() const 91 | { 92 | return d->serialNumber; 93 | } 94 | 95 | QString OnvifDeviceInformation::hardwareId() const 96 | { 97 | return d->hardwareId; 98 | } 99 | 100 | QDebug operator<< (QDebug debug, const OnvifDeviceInformation& d) 101 | { 102 | QDebugStateSaver saver(debug); 103 | debug.nospace() << "(Manufacturer: " << d.manufacturer() 104 | << ", Model: " << d.model() 105 | << ", FirmwareVersion: " << d.firmwareVersion() 106 | << ", SerialNumber: " << d.serialNumber() 107 | << ", HardwareId: " << d.hardwareId() << ')'; 108 | return debug; 109 | } 110 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 6 | 7 | # ONVIFViewer 8 | 9 | **ONVIF camera viewer for Plasma Mobile and Linux desktop** 10 | 11 | The goal of this project is to replace the proprietary app that was needed to configure and view my IP camera. The ONVIF protocol can be used to view and configure many types of camera's and is a open standard that can be implemented using standard SOAP libraries. Using Qt5 for the back-end and Kirigami UI framework makes this application a cross-platform solution. The primary focus is Plasma mobile and the Linux desktop, but an Android build is also available. 12 | 13 | This project was started as part of the [ONVIF Open Source Spotlight Challange](https://onvif-spotlight.bemyapp.com/#/projects/5ae0bbf7f98fde00047f0605) and the application finished in [fourth place](https://www.onvif.org/blog/2018/07/onvif-challenge-announces-top-10/) (out of 37 submissions). 14 | Before this project started, there was no open-source application for viewing ONVIF cameras for Plasma Mobile and Linux desktop. Neither is there a simple to use open-source C++ library to communicate with ONVIF cameras. The communication with the camera is implemented from scratch (using KDSoap) and modular designed, so that it can be separated into a reusable library at a later stage. 15 | 16 | 17 | ## Current state 18 | 19 | I stopped development on this project. I was fun to create this application, but I don't have a usecase for my camera anymore. Therefore I have lost interest in adding new features. 20 | 21 | I also found out that most bugs reported are from cameras that don't comply to the ONVIF specification. As I don't have such camera available it is not possible to fix that issue. This left multiple issue unsolved. This is not motivating me. 22 | 23 | Also I had difficulties releasing this as full free software, because of the non-free license of the ONVIF specification itself. 24 | 25 | Feel free to send in merge request for your own developments. 26 | 27 | ## Flatpak 28 | On most Linux desktops you can install the application using Flatpak. 29 | 30 | 1) First install Flatpak itself using the instructions on their [website](https://www.flatpak.org/setup/). 31 | 2) Then you can install the application from the [ONVIFViewer flathub page](https://flathub.org/apps/details/net.meijn.onvifviewer). 32 | 33 | [Download on Flathub](https://flathub.org/apps/details/net.meijn.onvifviewer) 34 | 35 | ## Translations 36 | You can help translating this application using [Weblate](https://hosted.weblate.org/engage/onvifviewer/). You can login on the website and translate the texts to your language. The translations will be included in the next release. 37 | 38 | [Vertalingsstatus](https://hosted.weblate.org/engage/onvifviewer/?utm_source=widget) 39 | 40 | ## Donations 41 | You can donate via Bitcoin at [15PerwiiGxPf27AxVTYq7hGYJ52WfM9EWo](bitcoin:15PerwiiGxPf27AxVTYq7hGYJ52WfM9EWo). 42 | 43 | You can donate via PayPal via: [Donate](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=RNGGP3C6J84QU) 44 | 45 | You can donate via LiberaPay via: [Donate using Liberapay](https://liberapay.com/caspermeijn/donate) 46 | 47 | ## Building from source 48 | It is also possible to build the application yourself. This requires a recent Qt5, KDSoap and KDE libraries to be installed. Then build ONVIFViewer using CMake: 49 | 50 | git clone https://gitlab.com/caspermeijn/onvifviewer.git 51 | mkdir build-onvifviewer 52 | cd build-onvifviewer 53 | cmake -DCMAKE_BUILD_TYPE=Release ../onvifviewer 54 | make 55 | sudo make install 56 | cd .. 57 | 58 | ## Attribution 59 | Google Play and the Google Play logo are trademarks of Google LLC. 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /src/onvifdevicediscover.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2019 Casper Meijn 2 | * SPDX-License-Identifier: GPL-3.0-or-later 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | #include "onvifdevicediscover.h" 18 | 19 | #ifdef WITH_KDSOAP_WSDISCOVERY_CLIENT 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #endif 26 | 27 | OnvifDeviceDiscover::OnvifDeviceDiscover(QObject* parent) : 28 | QObject(parent) 29 | { 30 | qRegisterMetaType ("QObjectList"); 31 | 32 | #ifdef WITH_KDSOAP_WSDISCOVERY_CLIENT 33 | m_client = new WSDiscoveryClient(this); 34 | 35 | m_probeJob = new WSDiscoveryProbeJob(m_client); 36 | connect(m_probeJob, &WSDiscoveryProbeJob::matchReceived, this, &OnvifDeviceDiscover::matchReceived); 37 | KDQName type("tdn:NetworkVideoTransmitter"); 38 | type.setNameSpace("http://www.onvif.org/ver10/network/wsdl"); 39 | m_probeJob->addType(type); 40 | #endif 41 | } 42 | 43 | bool OnvifDeviceDiscover::isAvailable() 44 | { 45 | #ifdef WITH_KDSOAP_WSDISCOVERY_CLIENT 46 | return true; 47 | #else 48 | return false; 49 | #endif 50 | } 51 | 52 | QObjectList OnvifDeviceDiscover::matchList() const 53 | { 54 | QObjectList list; 55 | for (auto match : m_matchMap.values()) { 56 | list.append(match); 57 | } 58 | return list; 59 | } 60 | 61 | void OnvifDeviceDiscover::start() 62 | { 63 | #ifdef WITH_KDSOAP_WSDISCOVERY_CLIENT 64 | m_client->start(); 65 | m_probeJob->start(); 66 | #endif 67 | } 68 | 69 | void OnvifDeviceDiscover::matchReceived(const WSDiscoveryTargetService& matchedService) 70 | { 71 | #ifdef WITH_KDSOAP_WSDISCOVERY_CLIENT 72 | OnvifDeviceDiscoverMatch* deviceMatch = m_matchMap.value(matchedService.endpointReference()); 73 | if (deviceMatch == nullptr) { 74 | deviceMatch = new OnvifDeviceDiscoverMatch(); 75 | } 76 | deviceMatch->m_endpoint = matchedService.endpointReference(); 77 | for (auto& scope : matchedService.scopeList()) { 78 | if (scope.scheme() == "onvif" && 79 | scope.authority().toLower() == "www.onvif.org") { 80 | auto splitPath = scope.path().split("/", QString::SkipEmptyParts); 81 | if (splitPath[0].toLower() == "name") { 82 | deviceMatch->m_name = splitPath[1]; 83 | } 84 | if (splitPath[0].toLower() == "hardware") { 85 | deviceMatch->m_hardware = splitPath[1]; 86 | } 87 | } 88 | } 89 | for (auto& xAddr : matchedService.xAddrList()) { 90 | deviceMatch->m_xAddr = xAddr; 91 | } 92 | deviceMatch->m_lastSeen = matchedService.lastSeen(); 93 | 94 | m_matchMap.insert(deviceMatch->m_endpoint, deviceMatch); 95 | emit matchListChanged(matchList()); 96 | #endif 97 | } 98 | 99 | QString OnvifDeviceDiscoverMatch::getHardware() const 100 | { 101 | return m_hardware; 102 | } 103 | 104 | QString OnvifDeviceDiscoverMatch::getEndpoint() const 105 | { 106 | return m_endpoint; 107 | } 108 | 109 | QUrl OnvifDeviceDiscoverMatch::getXAddr() const 110 | { 111 | return m_xAddr; 112 | } 113 | 114 | QString OnvifDeviceDiscoverMatch::getHost() const 115 | { 116 | return m_xAddr.authority(); 117 | } 118 | 119 | QString OnvifDeviceDiscoverMatch::getName() const 120 | { 121 | return m_name; 122 | } 123 | -------------------------------------------------------------------------------- /src/onvifdevicemanagermodel.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2018 Casper Meijn 2 | * SPDX-License-Identifier: GPL-3.0-or-later 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | #include "onvifdevicemanagermodel.h" 18 | 19 | #include "onvifdevice.h" 20 | #include "onvifdevicemanager.h" 21 | #include 22 | #include 23 | 24 | OnvifDeviceManagerModel::OnvifDeviceManagerModel(const OnvifDeviceManager* deviceManager, QObject* parent) : 25 | QAbstractListModel(parent), 26 | m_deviceManager(deviceManager) 27 | { 28 | connect(m_deviceManager, &OnvifDeviceManager::deviceListChanged, this, &OnvifDeviceManagerModel::deviceListChanged); 29 | deviceListChanged(); 30 | } 31 | 32 | int OnvifDeviceManagerModel::rowCount(const QModelIndex&) const 33 | { 34 | return m_deviceManager->deviceList().count(); 35 | } 36 | 37 | QVariant OnvifDeviceManagerModel::data(const QModelIndex& index, int role) const 38 | { 39 | Q_ASSERT(index.row() < m_deviceManager->deviceList().size()); 40 | OnvifDevice* device = m_deviceManager->deviceList().value(index.row()); 41 | if (!device) { 42 | qDebug() << "OnvifDeviceManagerModel" << "Invalid index" << index; 43 | return QVariant(); 44 | } 45 | 46 | if (role == Qt::DisplayRole) { 47 | return QVariant::fromValue(device); 48 | } 49 | 50 | const QMetaObject* metaObject = device->metaObject(); 51 | if (role >= Qt::UserRole && role < Qt::UserRole + metaObject->propertyCount()) { 52 | const QMetaProperty& prop = metaObject->property(role - Qt::UserRole); 53 | return device->property(prop.name()); 54 | } 55 | qDebug() << "OnvifDeviceManagerModel" << "Unknown role" << index << role; 56 | return QVariant(); 57 | } 58 | 59 | QVariant OnvifDeviceManagerModel::headerData(int section, Qt::Orientation orientation, int role) const 60 | { 61 | qDebug() << "headerData" << section << orientation << role; 62 | return QVariant(); 63 | } 64 | 65 | QHash OnvifDeviceManagerModel::roleNames() const 66 | { 67 | QHash roles; 68 | roles[Qt::DisplayRole] = "device"; 69 | const QMetaObject& metaObject = OnvifDevice::staticMetaObject; 70 | for (int i = 0; i < metaObject.propertyCount(); i++) { 71 | roles[Qt::UserRole + i] = QByteArray(metaObject.property(i).name()); 72 | } 73 | return roles; 74 | } 75 | 76 | void OnvifDeviceManagerModel::deviceListChanged() 77 | { 78 | int indexOfMethod = this->metaObject()->indexOfMethod("deviceChanged()"); 79 | Q_ASSERT(indexOfMethod != -1); 80 | const QMetaMethod& targetSlot = this->metaObject()->method(indexOfMethod); 81 | 82 | beginResetModel(); 83 | const auto& deviceList = m_deviceManager->deviceList(); 84 | for (auto& device : deviceList) { 85 | const QMetaObject* metaObject = device->metaObject(); 86 | for (int i = 0; i < metaObject->propertyCount(); i++) { 87 | const QMetaProperty& prop = metaObject->property(i); 88 | if (prop.hasNotifySignal()) { 89 | connect(device, prop.notifySignal(), this, targetSlot); 90 | } 91 | } 92 | } 93 | endResetModel(); 94 | } 95 | 96 | void OnvifDeviceManagerModel::deviceChanged() 97 | { 98 | auto* device = qobject_cast (sender()); 99 | Q_ASSERT(device); 100 | 101 | int i = m_deviceManager->deviceList().indexOf(device); 102 | emit dataChanged(index(i), index(i)); 103 | } 104 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2018-2019 Casper Meijn 2 | # SPDX-License-Identifier: GPL-3.0-or-later 3 | # 4 | # This program is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | cmake_minimum_required(VERSION 3.7) 18 | 19 | project(onvifviewer VERSION "0.13") 20 | 21 | # Find the number of commits since the last release and use this as version patch number 22 | find_package(Git) 23 | if(GIT_FOUND) 24 | execute_process( 25 | COMMAND "${GIT_EXECUTABLE}" rev-list v${PROJECT_VERSION}...HEAD 26 | COMMAND wc -l 27 | WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" 28 | RESULT_VARIABLE result OUTPUT_VARIABLE output 29 | ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) 30 | if(result EQUAL 0) 31 | message("Number of commits since last git tag: ${output}") 32 | project(${PROJECT_NAME} VERSION "${PROJECT_VERSION}.${output}") 33 | endif() 34 | endif() 35 | 36 | SET(CMAKE_CXX_STANDARD 11) 37 | 38 | set(CMAKE_INCLUDE_CURRENT_DIR ON) 39 | set(CMAKE_AUTOMOC ON) 40 | set(CMAKE_AUTORCC ON) 41 | 42 | include(FeatureSummary) 43 | 44 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") 45 | find_package(Gettext 0.19 REQUIRED) 46 | find_package(ECM 5.44.0 REQUIRED NO_MODULE) 47 | set_package_properties(ECM PROPERTIES TYPE REQUIRED DESCRIPTION "Extra CMake Modules." URL "https://projects.kde.org/projects/kdesupport/extra-cmake-modules") 48 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH}) 49 | find_package(KDSoap 1.8.0 REQUIRED) 50 | set_package_properties(KDSoap PROPERTIES DESCRIPTION "A Qt-based client-side and server-side SOAP component" URL "http://www.kdab.com/products/kd-soap" TYPE REQUIRED PURPOSE "Support for SOAP client protocol") 51 | find_package(KF5 5.44 REQUIRED CoreAddons I18n) 52 | find_package(KF5Kirigami2 5.52 REQUIRED) 53 | find_package(Qt5 5.12.0 REQUIRED NO_MODULE COMPONENTS Core Svg Qml Quick QuickControls2 Xml) 54 | set_package_properties(Qt5 PROPERTIES DESCRIPTION "The Qt5 framework" URL "http://www.qt.io" TYPE REQUIRED) 55 | find_package(KDSoapWSDiscoveryClient 0.1) 56 | set_package_properties(KDSoapWSDiscoveryClient PROPERTIES DESCRIPTION "KDSoap WS-Discovery client" URL "https://gitlab.com/caspermeijn/kdsoap-ws-discovery-client" TYPE OPTIONAL) 57 | find_package(QtAV 1.12.0) 58 | set_package_properties(QtAV PROPERTIES DESCRIPTION "QtAV Multimedia library" URL "https://github.com/wang-bin/QtAV" TYPE OPTIONAL) 59 | 60 | if(NOT ANDROID) 61 | find_package(KF5 5.44 REQUIRED XmlGui) 62 | add_definitions(-DWITH_KF5_XML_GUI) 63 | endif() 64 | 65 | include(ECMQMLModules) 66 | include(ECMSetupVersion) 67 | include(KDEInstallDirs) 68 | include(KDECMakeSettings) 69 | include(KDECompilerSettings NO_POLICY_SCOPE) 70 | 71 | ##TODO: figure out whye these qml module checks fail for gitlab-ci 72 | #ecm_find_qmlmodule(org.kde.kirigami 2.5 REQUIRED) 73 | #ecm_find_qmlmodule(QtMultimedia 5.9 REQUIRED) 74 | #ecm_find_qmlmodule(QtQml.Models 2.1 REQUIRED) 75 | #ecm_find_qmlmodule(QtQuick 2.9 REQUIRED) 76 | #ecm_find_qmlmodule(QtQuick.Controls 1.4 REQUIRED) 77 | ##TODO: figure out why QtQuick.Controls 2.3 is not found 78 | ##ecm_find_qmlmodule(QtQuick.Controls 2.3 REQUIRED) 79 | ##ecm_find_qmlmodule(QtQuick.Controls.Material 2.3 REQUIRED) 80 | #ecm_find_qmlmodule(QtQuick.Layouts 1.3 REQUIRED) 81 | 82 | # Enable extra warnings 83 | add_compile_options(-pedantic-errors -Wconversion -Wsign-conversion) 84 | 85 | add_subdirectory(android) 86 | add_subdirectory(libOnvifConnect) 87 | add_subdirectory(src) 88 | add_subdirectory(desktop) 89 | add_subdirectory(fastlane) 90 | add_subdirectory(po) 91 | enable_testing() 92 | add_subdirectory(autotests) 93 | 94 | feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) 95 | -------------------------------------------------------------------------------- /src/onvifdevicemanager.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2018 Casper Meijn 2 | * SPDX-License-Identifier: GPL-3.0-or-later 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | #include "onvifdevice.h" 18 | #include "onvifdevicemanager.h" 19 | #include "onvifdeviceservice.h" 20 | #include "onvifmediaservice.h" 21 | 22 | #ifdef WITH_KF5_XML_GUI 23 | #include 24 | #include 25 | #endif 26 | #include 27 | #include 28 | #include 29 | 30 | OnvifDeviceManager::OnvifDeviceManager(QObject* parent) : 31 | QObject(parent) 32 | { 33 | qRegisterMetaType> ("QList"); 34 | } 35 | 36 | void OnvifDeviceManager::loadDevices() 37 | { 38 | Q_ASSERT(m_deviceList.isEmpty()); 39 | 40 | QSettings settings; 41 | int size = settings.beginReadArray("devices"); 42 | for (int i = 0; i < size; i++) { 43 | settings.setArrayIndex(i); 44 | OnvifDevice* device = createNewDevice(); 45 | device->setDeviceName(settings.value("deviceName").toString()); 46 | device->setHostName(settings.value("hostName").toString()); 47 | device->setUserName(settings.value("userName").toString()); 48 | device->setPassword(settings.value("password").toString()); 49 | device->setPreferContinuousMove(settings.value("preferContinuousMove").toBool()); 50 | device->setPreferredVideoStreamProtocol(settings.value("preferredVideoStreamProtocol").toString()); 51 | 52 | device->connectToDevice(); 53 | } 54 | settings.endArray(); 55 | } 56 | 57 | void OnvifDeviceManager::saveDevices() 58 | { 59 | QSettings settings; 60 | settings.beginWriteArray("devices"); 61 | for (int i = 0; i < m_deviceList.count(); i++) { 62 | auto device = m_deviceList.at(i); 63 | settings.setArrayIndex(i); 64 | settings.setValue("deviceName", device->deviceName()); 65 | settings.setValue("hostName", device->hostName()); 66 | settings.setValue("userName", device->userName()); 67 | settings.setValue("password", device->password()); 68 | settings.setValue("preferContinuousMove", device->preferContinuousMove()); 69 | settings.setValue("preferredVideoStreamProtocol", device->preferredVideoStreamProtocol()); 70 | } 71 | settings.endArray(); 72 | } 73 | 74 | OnvifDevice* OnvifDeviceManager::createNewDevice() 75 | { 76 | auto* device = new OnvifDevice(this); 77 | 78 | m_deviceList.append(device); 79 | emit deviceListChanged(m_deviceList); 80 | return device; 81 | } 82 | 83 | QList OnvifDeviceManager::deviceList() const 84 | { 85 | return m_deviceList; 86 | } 87 | 88 | OnvifDevice* OnvifDeviceManager::at(int i) 89 | { 90 | return m_deviceList.at(i); 91 | } 92 | 93 | int OnvifDeviceManager::appendDevice() 94 | { 95 | createNewDevice(); 96 | return m_deviceList.count() - 1; 97 | } 98 | 99 | void OnvifDeviceManager::removeDevice(int i) 100 | { 101 | OnvifDevice* device = m_deviceList.takeAt(i); 102 | emit deviceListChanged(m_deviceList); 103 | device->deleteLater(); 104 | } 105 | 106 | int OnvifDeviceManager::indexOf(OnvifDevice* device) 107 | { 108 | return m_deviceList.indexOf(device); 109 | } 110 | 111 | int OnvifDeviceManager::size() 112 | { 113 | return m_deviceList.size(); 114 | } 115 | 116 | #ifdef WITH_KF5_XML_GUI 117 | void iconLoaderWorkaround() 118 | { 119 | //TODO: For some reason it is needed to link the KF5::XmlGui library for the theme icons to be loaded correctly in flatpak 120 | new KAboutApplicationDialog(KAboutData::applicationData(), nullptr); 121 | } 122 | #endif 123 | -------------------------------------------------------------------------------- /fastlane/convert_appstream_to_fastlane.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright (C) 2019 Casper Meijn 4 | # SPDX-License-Identifier: GPL-3.0-or-later 5 | # 6 | # This program is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with this program. If not, see . 18 | 19 | import xml.etree.ElementTree as ET 20 | import argparse 21 | from pathlib import Path 22 | 23 | parser = argparse.ArgumentParser(description='Convert appstream metadata to fastlane metadata.') 24 | parser.add_argument('--appstream', required=True, help='path to the appstream metadata file') 25 | parser.add_argument('--fastlane', required=True, help='path to the fastlane metadata directory') 26 | args = parser.parse_args() 27 | 28 | fastlane_path = Path(args.fastlane) 29 | fastlane_path.mkdir(0o755, True, True) 30 | 31 | def get_lang_from_attib(tag): 32 | lang = tag.attrib.get('{http://www.w3.org/XML/1998/namespace}lang', 'en-GB') 33 | lang = lang.replace('_', '-') 34 | if lang == 'nb-NO': 35 | lang = 'no-NO' 36 | if lang == 'de': 37 | lang = 'de-DE' 38 | if lang == 'it': 39 | lang = 'it-IT' 40 | return lang 41 | 42 | tree = ET.parse(args.appstream) 43 | root = tree.getroot() 44 | 45 | for name in root.findall('name'): 46 | lang = get_lang_from_attib(name) 47 | lang_dir = fastlane_path.joinpath(lang) 48 | lang_dir.mkdir(0o755, True, True) 49 | name_file = lang_dir.joinpath('title.txt') 50 | name_file.write_text(name.text) 51 | 52 | for summary in root.findall('summary'): 53 | lang = get_lang_from_attib(summary) 54 | lang_dir = fastlane_path.joinpath(lang) 55 | lang_dir.mkdir(0o755, True, True) 56 | desc_file = lang_dir.joinpath('short_description.txt') 57 | desc_file.write_text(summary.text) 58 | 59 | description_map = {} 60 | for description in root.findall('./description/p'): 61 | lang = get_lang_from_attib(description) 62 | if lang in description_map: 63 | description_map[lang] = description_map[lang] + '\n' 64 | else: 65 | description_map[lang] = "" 66 | description_map[lang] = description_map[lang] + description.text + '\n' 67 | 68 | for lang, text in description_map.items(): 69 | lang_dir = fastlane_path.joinpath(lang) 70 | lang_dir.mkdir(0o755, True, True) 71 | desc_file = lang_dir.joinpath('full_description.txt') 72 | desc_file.write_text(text) 73 | 74 | lang = 'en-GB' 75 | for release in root.findall('./releases/release'): 76 | version = release.attrib.get('version') 77 | base_versioncode = 0 78 | for version_part in version.split('.'): 79 | base_versioncode = int(version_part) + base_versioncode * 100 80 | base_versioncode *= 100 81 | 82 | text = "" 83 | for paragraph in release.findall('./description/*'): 84 | if paragraph.tag == 'p': 85 | paragraph_lang = get_lang_from_attib(paragraph) 86 | if paragraph_lang == lang: 87 | text += paragraph.text + '\n' 88 | else: 89 | for listitem in paragraph.findall('li'): 90 | paragraph_lang = get_lang_from_attib(listitem) 91 | if paragraph_lang == lang: 92 | text += '- ' + listitem.text + '\n' 93 | 94 | lang_dir = fastlane_path.joinpath(lang) 95 | changelog_dir = lang_dir.joinpath('changelogs') 96 | changelog_dir.mkdir(0o755, True, True) 97 | 98 | # From version 0.12, multiple APKs are made; 0 = base APK, 1 = armv7, 2 = aarch64 99 | if base_versioncode >= 1200: 100 | versioncode = base_versioncode * 10 101 | versioncodelist = [versioncode, versioncode + 1, versioncode + 2] 102 | else: 103 | versioncodelist = [base_versioncode] 104 | for versioncode in versioncodelist: 105 | changelog_file = changelog_dir.joinpath(str(versioncode) + '.txt') 106 | changelog_file.write_text(text) 107 | 108 | fastlane_path.touch() 109 | -------------------------------------------------------------------------------- /android/AndroidManifest.xml.in: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /libOnvifConnect/onvifmediaprofile.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2018 Casper Meijn 2 | * SPDX-License-Identifier: GPL-3.0-or-later 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | #include "onvifmediaprofile.h" 18 | 19 | #include 20 | #include "wsdl_media.h" 21 | #include "wsdl_media2.h" 22 | 23 | class OnvifMediaProfilePrivate : public QSharedData 24 | { 25 | public: 26 | OnvifMediaProfilePrivate() {;} 27 | 28 | OnvifMediaProfilePrivate(const OnvifSoapMedia::TT__Profile& profile) : 29 | fixed(profile.fixed()), 30 | name(profile.name()), 31 | token(profile.token().value()), 32 | ptzNodeToken(profile.pTZConfiguration().nodeToken()), 33 | resolutionPixels(profile.videoEncoderConfiguration().resolution().height() * profile.videoEncoderConfiguration().resolution().width()) 34 | { 35 | Q_ASSERT(token.size()); 36 | switch (profile.videoEncoderConfiguration().encoding()) { 37 | case OnvifSoapMedia::TT__VideoEncoding::JPEG: 38 | videoEncoding = "JPEG"; 39 | break; 40 | case OnvifSoapMedia::TT__VideoEncoding::H264: 41 | videoEncoding = "H264"; 42 | break; 43 | case OnvifSoapMedia::TT__VideoEncoding::MPEG4: 44 | videoEncoding = "MPV4-ES"; 45 | break; 46 | } 47 | } 48 | 49 | OnvifMediaProfilePrivate(const OnvifSoapMedia2::TR2__MediaProfile& profile) : 50 | fixed(profile.fixed()), 51 | name(profile.name()), 52 | token(profile.token().value()), 53 | ptzNodeToken(profile.configurations().pTZ().nodeToken()), 54 | videoEncoding(profile.configurations().videoEncoder().encoding()), 55 | resolutionPixels(profile.configurations().videoEncoder().resolution().height() * profile.configurations().videoEncoder().resolution().width()) 56 | { 57 | Q_ASSERT(token.size()); 58 | } 59 | 60 | bool fixed = false; 61 | QString name; 62 | QString token; 63 | QString ptzNodeToken; 64 | QString videoEncoding; 65 | long resolutionPixels = 0; 66 | }; 67 | 68 | OnvifMediaProfile::OnvifMediaProfile() : 69 | d(new OnvifMediaProfilePrivate()) 70 | { 71 | } 72 | 73 | OnvifMediaProfile::OnvifMediaProfile(const OnvifMediaProfile& other) = default; 74 | 75 | OnvifMediaProfile::OnvifMediaProfile(const OnvifSoapMedia::TT__Profile& profile) : 76 | d(new OnvifMediaProfilePrivate(profile)) 77 | { 78 | } 79 | 80 | OnvifMediaProfile::OnvifMediaProfile(const OnvifSoapMedia2::TR2__MediaProfile& profile) : 81 | d(new OnvifMediaProfilePrivate(profile)) 82 | { 83 | } 84 | 85 | OnvifMediaProfile::~OnvifMediaProfile() = default; 86 | 87 | OnvifMediaProfile& OnvifMediaProfile::operator= (const OnvifMediaProfile& other) 88 | { 89 | if (this != &other) { 90 | OnvifMediaProfile copy(other); 91 | d.swap(copy.d); 92 | } 93 | return *this; 94 | } 95 | 96 | QString OnvifMediaProfile::name() const 97 | { 98 | return d->name; 99 | } 100 | 101 | void OnvifMediaProfile::setName(const QString& name) 102 | { 103 | d->name = name; 104 | } 105 | 106 | QString OnvifMediaProfile::token() const 107 | { 108 | return d->token; 109 | } 110 | 111 | void OnvifMediaProfile::setToken(const QString& token) 112 | { 113 | d->token = token; 114 | } 115 | 116 | bool OnvifMediaProfile::fixed() const 117 | { 118 | return d->fixed; 119 | } 120 | 121 | void OnvifMediaProfile::setFixed(bool fixed) 122 | { 123 | d->fixed = fixed; 124 | } 125 | 126 | QString OnvifMediaProfile::ptzNodeToken() const 127 | { 128 | return d->ptzNodeToken; 129 | } 130 | 131 | QString OnvifMediaProfile::videoEncoding() const 132 | { 133 | return d->videoEncoding; 134 | } 135 | 136 | long OnvifMediaProfile::resolutionPixels() const 137 | { 138 | return d->resolutionPixels; 139 | } 140 | 141 | QDebug operator<< (QDebug debug, const OnvifMediaProfile& p) 142 | { 143 | QDebugStateSaver saver(debug); 144 | debug.nospace() << "(Fixed: " << p.fixed() 145 | << ", Name: " << p.name() 146 | << ", Token: " << p.token() 147 | << ", VideoEncoding: " << p.videoEncoding() 148 | << ", ResolutionPixels: " << p.resolutionPixels() << ')'; 149 | return debug; 150 | } 151 | -------------------------------------------------------------------------------- /src/DeviceSettingsPage.qml: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2018 Casper Meijn 2 | * SPDX-License-Identifier: GPL-3.0-or-later 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | import net.meijn.onvifviewer 1.0 18 | import org.kde.kirigami 2.6 as Kirigami 19 | import QtQuick 2.9 20 | import QtQuick.Controls 2.3 21 | import QtQuick.Controls.Material 2.3 22 | import QtQuick.Layouts 1.3 23 | 24 | Kirigami.ScrollablePage { 25 | property bool hasConnectionSettingsChanged: false 26 | property bool hasOtherSettingsChanged: false 27 | property bool isNewDevice: false 28 | 29 | title: isNewDevice ? i18n("New manual device") : i18n("Device settings") 30 | objectName: "settingsPage" 31 | 32 | onIsCurrentPageChanged: { 33 | if(!isCurrentPage) { 34 | if(hasConnectionSettingsChanged || hasOtherSettingsChanged) { 35 | if(hasConnectionSettingsChanged) { 36 | selectedDevice.reconnectToDevice() 37 | } 38 | deviceManager.saveDevices() 39 | hasConnectionSettingsChanged = false; 40 | hasOtherSettingsChanged = false 41 | } 42 | isNewDevice = false 43 | } 44 | } 45 | 46 | property OnvifDevice selectedDevice: deviceManager.at(selectedIndex) 47 | 48 | ColumnLayout { 49 | spacing: Kirigami.Units.gridUnit 50 | 51 | // TODO: Figure out why this FormLayout is broken if the Style=Default in qtquickcontrols2.conf and work correct if Style=Material 52 | Kirigami.FormLayout { 53 | id: layout 54 | Layout.fillWidth: true 55 | 56 | Kirigami.Separator { 57 | Kirigami.FormData.isSection: true 58 | Kirigami.FormData.label: i18n("Connection settings") 59 | } 60 | TextField { 61 | Kirigami.FormData.label: i18n("Camera name:") 62 | placeholderText: i18n("e.g. Backyard") 63 | text: selectedDevice && selectedDevice.deviceName 64 | onTextEdited: { 65 | hasOtherSettingsChanged = true 66 | selectedDevice.deviceName = text 67 | } 68 | } 69 | TextField { 70 | Kirigami.FormData.label: i18n("Hostname:") 71 | placeholderText: i18n("e.g. ipcam.local or 192.168.0.12") 72 | text: selectedDevice && selectedDevice.hostName 73 | onTextEdited: { 74 | hasConnectionSettingsChanged = true 75 | selectedDevice.hostName = text 76 | } 77 | } 78 | TextField { 79 | Kirigami.FormData.label: i18n("Username:") 80 | text: selectedDevice && selectedDevice.userName 81 | onTextEdited: { 82 | hasConnectionSettingsChanged = true 83 | selectedDevice.userName = text 84 | } 85 | } 86 | TextField { 87 | Kirigami.FormData.label: i18n("Password:") 88 | echoMode: TextInput.Password 89 | text: selectedDevice && selectedDevice.password 90 | onTextEdited: { 91 | hasConnectionSettingsChanged = true 92 | selectedDevice.password = text 93 | } 94 | } 95 | Kirigami.Separator { 96 | Kirigami.FormData.isSection: true 97 | Kirigami.FormData.label: i18n("Camera properties") 98 | } 99 | Switch { 100 | Kirigami.FormData.label: i18n("Enable camera movement fix") 101 | checked: selectedDevice && selectedDevice.preferContinuousMove 102 | onCheckedChanged: { 103 | hasOtherSettingsChanged = true 104 | selectedDevice.preferContinuousMove = checked 105 | } 106 | } 107 | } 108 | Button { 109 | text: i18n("Remove camera") 110 | onClicked: { 111 | pageStack.pop(); 112 | deviceManager.removeDevice(selectedIndex) 113 | deviceManager.saveDevices() 114 | } 115 | Layout.fillWidth: true 116 | Material.background: Material.Red 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /3rdparty/wsdl/www.onvif.org/ver10/pacs/types.xsd: -------------------------------------------------------------------------------- 1 | 2 | 28 | 33 | 34 | 35 | 36 | Type used to reference logical and physical entities. 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | General datastructure referenced by a token. 47 | Should be used as extension base. 48 | 49 | 50 | 51 | 52 | 53 | 54 | A service-unique identifier of the item. 55 | 56 | 57 | 58 | 59 | 60 | 61 | Type used for names of logical and physical entities. 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | Description is optional and the maximum length is device specific. 72 | If the length is more than maximum length, it is silently chopped to the maximum length 73 | supported by the device/service (which may be 0). 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | Type used to represent the numbers from 1 ,2 , 3,... 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | Attributes contains a Name and an optional Value and type. 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | Name of attribute. Key names starting with "ONVIF" (any case) are reserved for ONVIF 103 | use. 104 | 105 | 106 | 107 | 108 | 109 | Value of attribute 110 | 111 | 112 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /3rdparty/wsdl/docs.oasis-open.org/wsrf/bf-2.xsd: -------------------------------------------------------------------------------- 1 | 2 | 15 | 16 | 26 | 30 | 31 | 33 | 34 | 35 | Get access to the xml: attribute groups for xml:lang as declared on 'schema' 36 | and 'documentation' below 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 48 | 50 | 52 | 54 | 55 | 56 | 57 | 59 | 60 | 61 | 62 | 63 | 64 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /desktop/ApplicationIcon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 24 | 45 | 52 | 53 | 55 | 56 | 58 | image/svg+xml 59 | 61 | 62 | 64 | 65 | 67 | 69 | 71 | 73 | 75 | 77 | 79 | 80 | 81 | 82 | 87 | 95 | 96 | 101 | 104 | 109 | 118 | 124 | 125 | 132 | 139 | 145 | 151 | 152 | 153 | 154 | -------------------------------------------------------------------------------- /src/onvifdevice.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2018 Casper Meijn 2 | * SPDX-License-Identifier: GPL-3.0-or-later 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | #ifndef ONVIFDEVICE_H 18 | #define ONVIFDEVICE_H 19 | 20 | #include "onvifdeviceconnection.h" 21 | #include "onvifmediaprofile.h" 22 | #include 23 | #include 24 | #include 25 | 26 | class OnvifDeviceInformation; 27 | class OnvifSnapshotDownloader; 28 | 29 | class OnvifDevice : public QObject 30 | { 31 | Q_OBJECT 32 | Q_PROPERTY(QString deviceName READ deviceName WRITE setDeviceName NOTIFY deviceNameChanged) 33 | Q_PROPERTY(QString hostName READ hostName WRITE setHostName NOTIFY hostNameChanged) 34 | Q_PROPERTY(QString userName READ userName WRITE setUserName NOTIFY userNameChanged) 35 | Q_PROPERTY(QString password READ password WRITE setPassword NOTIFY passwordChanged) 36 | Q_PROPERTY(bool preferContinuousMove READ preferContinuousMove WRITE setPreferContinuousMove NOTIFY preferContinuousMoveChanged) 37 | Q_PROPERTY(QString preferredVideoStreamProtocol READ preferredVideoStreamProtocol WRITE setPreferredVideoStreamProtocol NOTIFY preferredVideoStreamProtocolChanged) 38 | Q_PROPERTY(QString errorString READ errorString NOTIFY errorStringChanged) 39 | Q_PROPERTY(OnvifDeviceInformation* deviceInformation READ deviceInformation NOTIFY deviceInformationChanged) 40 | Q_PROPERTY(bool supportsSnapshotUri READ supportsSnapshotUri NOTIFY supportsSnapshotUriChanged) 41 | Q_PROPERTY(QUrl snapshotUri READ snapshotUri NOTIFY snapshotUriChanged) 42 | Q_PROPERTY(QUrl streamUri READ streamUri NOTIFY streamUriChanged) 43 | Q_PROPERTY(bool isPanTiltSupported READ isPanTiltSupported) 44 | Q_PROPERTY(bool isPtzHomeSupported READ isPtzHomeSupported) 45 | Q_PROPERTY(bool isZoomSupported READ isZoomSupported) 46 | Q_PROPERTY(OnvifSnapshotDownloader* snapshotDownloader READ snapshotDownloader NOTIFY snapshotDownloaderChanged) 47 | public: 48 | explicit OnvifDevice(QObject* parent = nullptr); 49 | 50 | Q_INVOKABLE void connectToDevice(); 51 | Q_INVOKABLE void reconnectToDevice(); 52 | 53 | OnvifDeviceInformation* deviceInformation() const; 54 | OnvifSnapshotDownloader* snapshotDownloader() const; 55 | bool supportsSnapshotUri() const; 56 | QUrl snapshotUri() const; 57 | QUrl streamUri() const; 58 | QString errorString() const; 59 | 60 | QString deviceName() const; 61 | void setDeviceName(const QString& deviceName); 62 | 63 | QString hostName() const; 64 | void setHostName(const QString& hostName); 65 | 66 | QString userName() const; 67 | void setUserName(const QString& userName); 68 | 69 | QString password() const; 70 | void setPassword(const QString& password); 71 | 72 | bool isPanTiltSupported() const; 73 | bool isPtzHomeSupported() const; 74 | bool isZoomSupported() const; 75 | 76 | bool preferContinuousMove() const; 77 | void setPreferContinuousMove(bool preferContinuousMove); 78 | 79 | QString preferredVideoStreamProtocol() const; 80 | void setPreferredVideoStreamProtocol(const QString& preferredVideoStreamProtocol); 81 | 82 | void initByUrl(const QUrl& url); 83 | 84 | signals: 85 | void deviceNameChanged(const QString& deviceName); 86 | void hostNameChanged(const QString& hostName); 87 | void userNameChanged(const QString& userName); 88 | void passwordChanged(const QString& password); 89 | void preferContinuousMoveChanged(bool preferContinuousMove); 90 | void preferredVideoStreamProtocolChanged(const QString& preferredVideoStreamProtocol); 91 | void errorStringChanged(const QString& errorString); 92 | void deviceInformationChanged(OnvifDeviceInformation* deviceInformation); 93 | void supportsSnapshotUriChanged(bool supportsSnapshotUri); 94 | void snapshotUriChanged(const QUrl& url); 95 | void streamUriChanged(const QUrl& url); 96 | void snapshotDownloaderChanged(OnvifSnapshotDownloader* snapshotDownloader); 97 | 98 | public slots: 99 | void ptzUp(); 100 | void ptzDown(); 101 | void ptzLeft(); 102 | void ptzRight(); 103 | void ptzMove(float xFraction, float yFraction); 104 | void ptzHome(); 105 | void ptzSaveHomePosition(); 106 | void ptzStop(); 107 | void ptzZoomIn(); 108 | void ptzZoomOut(); 109 | 110 | private slots: 111 | void servicesAvailable(); 112 | void deviceInformationAvailable(const OnvifDeviceInformation& deviceInformation); 113 | void profileListAvailable(const QList& profileList); 114 | 115 | private: 116 | OnvifDeviceConnection m_connection; 117 | QString m_deviceName; 118 | QString m_hostName; 119 | QString m_userName; 120 | QString m_password; 121 | bool m_preferContinuousMove; 122 | QString m_preferredVideoStreamProtocol; 123 | OnvifMediaProfile m_selectedMediaProfile; 124 | OnvifDeviceInformation* m_cachedDeviceInformation; 125 | QTimer m_ptzStopTimer; 126 | OnvifSnapshotDownloader* m_cachedSnapshotDownloader; 127 | }; 128 | 129 | #endif // ONVIFDEVICE_H 130 | -------------------------------------------------------------------------------- /3rdparty/wsdl/www.onvif.org/ver20/analytics/rules.xsd: -------------------------------------------------------------------------------- 1 | 2 | 10 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | The total number of Motion Region Detector rules that can be created on the 24 | device. 25 | 26 | 27 | 28 | 29 | 30 | 31 | True if the device supports disarming a Motion Region Detector rule. 32 | 33 | 34 | 35 | 36 | 37 | 38 | True if the device supports defining a region using a Polygon instead of a 39 | Rectangle. 40 | 41 | 42 | 43 | 44 | 45 | 46 | For devices that support Polygons with limitations on the number of sides, 47 | provides the minimum and maximum number of sides that can be defined in the 48 | Polygon. 49 | 50 | 51 | 52 | 53 | 54 | 55 | Indicates the device can only support one sensitivity level for all defines 56 | motion detection regions. Changing the sensitivity for one region would be 57 | applied to all regions. 58 | 59 | 60 | 61 | 62 | 63 | 64 | True if the device will include the Name of the Rule to indicate the region 65 | that motion was detected in. 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | Provides the points of a Polygon in the VideoSourceConfiguration's Bounds 82 | element. If the device does not support Polygons, this structure must contain 83 | four points that represent a Rectangle. 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | Indicates if the Motion Region is Armed (detecting motion) or Disarmed (motion is 93 | not being detected). 94 | 95 | 96 | 97 | 98 | 99 | 100 | Indicates the sensitivity level of the motion detector for this region. The 101 | sensitivity value is normalized where 0 represents the lower sensitivity where 102 | significant motion is required to trigger an alarm and 1 represents the higher 103 | sensitivity where very little motion is required to trigger an alarm. 104 | 105 | 106 | 107 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /desktop/net.meijn.onvifviewer.appdata.xml.in: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | net.meijn.onvifviewer.desktop 6 | CC0-1.0 7 | GPL-3.0+ 8 | ONVIFViewer 9 | View and control network cameras using the ONVIF protocol 10 | 11 |

Use this open-source app to view your network cameras using the ONVIF protocol.

12 |

The development of this app was started as part of the ONVIF Spotlight Challenge.

13 |

You can connect to your network camera and view the video of it. If the camera is controllable you can move it as well.

14 |
15 | Casper Meijn 16 | https://gitlab.com/caspermeijn/onvifviewer 17 | https://gitlab.com/caspermeijn/onvifviewer/issues 18 | https://gitlab.com/caspermeijn/onvifviewer/blob/master/README.md#donations 19 | https://hosted.weblate.org/engage/onvifviewer/ 20 | net.meijn.onvifviewer.desktop 21 | 22 | 23 | The camera overview page 24 | https://gitlab.com/caspermeijn/onvifviewer/raw/master/desktop/screenshot1.png 25 | 26 | 27 | The camera settings page 28 | https://gitlab.com/caspermeijn/onvifviewer/raw/master/desktop/screenshot2.png 29 | 30 | 31 | onvifviewer 32 | casper@meijn.net 33 | 34 | onvifviewer 35 | 36 | 37 | none 38 | 39 | 40 | 41 | 42 |

This is a minor release, with the following changes:

43 |
    44 |
  • Some small improvements
  • 45 |
  • Now requires Qt 5.12
  • 46 |
  • Removed option for including breeze icons in the binary, however is it configured as fallback theme
  • 47 |
48 |
49 |
50 | 51 | 52 |

This is a minor release, with the following improvements:

53 |
    54 |
  • Added support for camera discovery
  • 55 |
  • Fixed video viewer for Android
  • 56 |
  • Improved translations
  • 57 |
  • Some small improvements
  • 58 |
59 |
60 |
61 | 62 | 63 |

This is a minor release, with the following improvements:

64 |
    65 |
  • Improved support for older devices
  • 66 |
  • Show multiple cameras if room available
  • 67 |
  • Improved translations and added new langagues
  • 68 |
  • Several internal improvements
  • 69 |
70 |
71 |
72 | 73 | 74 |

This is a minor release, with the following improvements:

75 |
    76 |
  • Improved support for older devices
  • 77 |
  • Fixed a potential crash
  • 78 |
  • Several internal improvements
  • 79 |
80 |
81 |
82 | 83 | 84 |

This is a minor release, with the following improvements:

85 |
    86 |
  • Added donation instructions
  • 87 |
  • Use breeze icons as fallback theme
  • 88 |
89 |
90 |
91 | 92 | 93 |

This is a minor release, with the following improvements:

94 |
    95 |
  • Added opening cameras by URL
  • 96 |
  • Improved snapshot downloading
  • 97 |
  • Improved translations and added Norwegian
  • 98 |
99 |
100 |
101 | 102 | 103 |

This is a minor release, with the following improvements:

104 |
    105 |
  • Improved UI style by using Kirigami cards
  • 106 |
  • Improved translations by supporting Weblate
  • 107 |
  • Made demo cameras optional, by moving them to the add camera button
  • 108 |
  • Some small improvements
  • 109 |
110 |
111 |
112 | 113 | 114 |

This is a minor release, with the following improvements:

115 |
    116 |
  • Renamed internal application name. Note: this causes the configuration file to reset
  • 117 |
  • Added internationalization support with Brazilian and Dutch translations
  • 118 |
  • Replaced demo cameras
  • 119 |
  • Several internal improvements
  • 120 |
121 |
122 |
123 | 124 | 125 |

This is a minor release, with the following improvements:

126 |
    127 |
  • Added workaround for cameras that don't support relative movement properly
  • 128 |
  • Added support for zoom'ing
  • 129 |
  • Improved build system
  • 130 |
131 |
132 |
133 |
134 |
135 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2018-2019 Casper Meijn 2 | * SPDX-License-Identifier: GPL-3.0-or-later 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include "onvifdevicediscover.h" 29 | #include "onvifdevicemanager.h" 30 | #include "onvifdevicemanagermodel.h" 31 | #include "onvifdevice.h" 32 | #include "onvifdeviceinformation.h" 33 | #include "onvifsnapshotdownloader.h" 34 | #include "onvifsnapshotviewer.h" 35 | #include "version.h" 36 | 37 | Q_DECL_EXPORT int main(int argc, char* argv[]) 38 | { 39 | #if defined(Q_OS_WIN) 40 | QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); 41 | #endif 42 | 43 | QApplication app(argc, argv); 44 | 45 | QIcon::setFallbackThemeName("breeze"); 46 | 47 | KLocalizedString::setApplicationDomain("onvifviewer"); 48 | QCoreApplication::setOrganizationName("CasperMeijn"); 49 | QCoreApplication::setOrganizationDomain("meijn.net"); 50 | QCoreApplication::setApplicationName("ONVIFViewer"); 51 | QCoreApplication::setApplicationVersion(onvifviewer_VERSION_STRING); 52 | app.setWindowIcon(QIcon::fromTheme(QStringLiteral("net.meijn.onvifviewer"))); 53 | 54 | KAboutData about("onvifviewer", i18n("ONVIFViewer"), onvifviewer_VERSION_STRING, 55 | i18n("View and control network cameras using the ONVIF protocol"), 56 | KAboutLicense::GPL_V3, 57 | "Copyright (C) 2018-2019 Casper Meijn ", "", 58 | "https://gitlab.com/caspermeijn/onvifviewer", 59 | "https://gitlab.com/caspermeijn/onvifviewer/issues"); 60 | about.setTranslator(i18nc("NAME OF TRANSLATORS", "Your names"), 61 | i18nc("EMAIL OF TRANSLATORS", "Your emails")); 62 | about.setOrganizationDomain("meijn.net"); 63 | about.setDesktopFileName("net.meijn.onvifviewer"); 64 | //TODO: setProgramLogo is needed, because Kirigami doesn't show the QApplication::windowIcon 65 | about.setProgramLogo(app.windowIcon()); 66 | about.addAuthor("Casper Meijn", i18n("Main developer"), QStringLiteral("casper@meijn.net")); 67 | KAboutData::setApplicationData(about); 68 | 69 | QCommandLineParser commandLineParser; 70 | commandLineParser.setApplicationDescription(i18n("View and control network cameras using the ONVIF protocol")); 71 | commandLineParser.addHelpOption(); 72 | commandLineParser.addVersionOption(); 73 | commandLineParser.addOption({"test", "test description", "test_name"}); 74 | commandLineParser.process(app); 75 | 76 | OnvifDeviceManager deviceManager; 77 | deviceManager.loadDevices(); 78 | 79 | OnvifDeviceManagerModel deviceManagerModel(&deviceManager); 80 | 81 | qmlRegisterType ("net.meijn.onvifviewer", 1, 0, "OnvifDevice"); 82 | qmlRegisterType ("net.meijn.onvifviewer", 1, 0, "OnvifDeviceInformation"); 83 | qmlRegisterType ("net.meijn.onvifviewer", 1, 0, "OnvifSnapshotDownloader"); 84 | qmlRegisterType ("net.meijn.onvifviewer", 1, 0, "OnvifSnapshotViewer"); 85 | 86 | OnvifDeviceDiscover deviceDiscover; 87 | deviceDiscover.start(); 88 | qmlRegisterType ("net.meijn.onvifviewer", 1, 0, "OnvifDeviceDiscover"); 89 | 90 | QQmlApplicationEngine engine; 91 | QQmlFileSelector* selector = new QQmlFileSelector(&engine); 92 | #ifdef WITH_QTAV 93 | selector->setExtraSelectors(QStringList() << "qtav"); 94 | #else 95 | Q_UNUSED(selector); 96 | #endif 97 | KLocalizedContext localizedContext; 98 | engine.rootContext()->setContextObject(&localizedContext); 99 | engine.rootContext()->setContextProperty("deviceManagerModel", &deviceManagerModel); 100 | engine.rootContext()->setContextProperty("deviceManager", &deviceManager); 101 | engine.rootContext()->setContextProperty("deviceDiscover", &deviceDiscover); 102 | engine.rootContext()->setContextProperty(QStringLiteral("onvifviewerAboutData"), QVariant::fromValue(KAboutData::applicationData())); 103 | 104 | engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); 105 | if (engine.rootObjects().isEmpty()) { 106 | return 12; 107 | } 108 | 109 | if (commandLineParser.isSet("test")) { 110 | QString testOption = commandLineParser.value("test"); 111 | if (testOption == "startup") { 112 | qDebug() << "Startup test activated, therefore the application will close automatically"; 113 | QTimer::singleShot(0, &app, &QGuiApplication::quit); 114 | } else { 115 | qFatal("Invalid test selected"); 116 | } 117 | } 118 | 119 | if (!commandLineParser.positionalArguments().isEmpty()) { 120 | auto url = QUrl(commandLineParser.positionalArguments().constFirst()); 121 | if (url.isValid()) { 122 | OnvifDevice* device = deviceManager.createNewDevice(); 123 | device->initByUrl(url); 124 | device->connectToDevice(); 125 | QVariant variantDevice = QVariant::fromValue (device); 126 | engine.rootObjects().constFirst()->setProperty("previewDevice", variantDevice); 127 | } 128 | } 129 | 130 | return QApplication::exec(); 131 | } 132 | -------------------------------------------------------------------------------- /3rdparty/wsdl/www.w3.org/2005/08/addressing/ws-addr.xsd: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | -------------------------------------------------------------------------------- /3rdparty/wsdl/www.w3.org/2003/05/soap-envelope: -------------------------------------------------------------------------------- 1 | 17 | 18 | 22 | 23 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | Elements replacing the wildcard MUST be namespace qualified, but can be in the targetNamespace 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 60 | 61 | 62 | 63 | 64 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | Fault reporting structure 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 106 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 126 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | -------------------------------------------------------------------------------- /LICENSES/CC0-1.0.txt: -------------------------------------------------------------------------------- 1 | Creative Commons Legal Code 2 | 3 | CC0 1.0 Universal CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES 4 | NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE 5 | AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION 6 | ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE USE 7 | OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER, AND DISCLAIMS 8 | LIABILITY FOR DAMAGES RESULTING FROM THE USE OF THIS DOCUMENT OR THE INFORMATION 9 | OR WORKS PROVIDED HEREUNDER. 10 | 11 | Statement of Purpose 12 | 13 | The laws of most jurisdictions throughout the world automatically confer exclusive 14 | Copyright and Related Rights (defined below) upon the creator and subsequent 15 | owner(s) (each and all, an "owner") of an original work of authorship and/or 16 | a database (each, a "Work"). 17 | 18 | Certain owners wish to permanently relinquish those rights to a Work for the 19 | purpose of contributing to a commons of creative, cultural and scientific 20 | works ("Commons") that the public can reliably and without fear of later claims 21 | of infringement build upon, modify, incorporate in other works, reuse and 22 | redistribute as freely as possible in any form whatsoever and for any purposes, 23 | including without limitation commercial purposes. These owners may contribute 24 | to the Commons to promote the ideal of a free culture and the further production 25 | of creative, cultural and scientific works, or to gain reputation or greater 26 | distribution for their Work in part through the use and efforts of others. 27 | 28 | For these and/or other purposes and motivations, and without any expectation 29 | of additional consideration or compensation, the person associating CC0 with 30 | a Work (the "Affirmer"), to the extent that he or she is an owner of Copyright 31 | and Related Rights in the Work, voluntarily elects to apply CC0 to the Work 32 | and publicly distribute the Work under its terms, with knowledge of his or 33 | her Copyright and Related Rights in the Work and the meaning and intended 34 | legal effect of CC0 on those rights. 35 | 36 | 1. Copyright and Related Rights. A Work made available under CC0 may be protected 37 | by copyright and related or neighboring rights ("Copyright and Related Rights"). 38 | Copyright and Related Rights include, but are not limited to, the following: 39 | 40 | i. the right to reproduce, adapt, distribute, perform, display, communicate, 41 | and translate a Work; 42 | 43 | ii. moral rights retained by the original author(s) and/or performer(s); 44 | 45 | iii. publicity and privacy rights pertaining to a person's image or likeness 46 | depicted in a Work; 47 | 48 | iv. rights protecting against unfair competition in regards to a Work, subject 49 | to the limitations in paragraph 4(a), below; 50 | 51 | v. rights protecting the extraction, dissemination, use and reuse of data 52 | in a Work; 53 | 54 | vi. database rights (such as those arising under Directive 96/9/EC of the 55 | European Parliament and of the Council of 11 March 1996 on the legal protection 56 | of databases, and under any national implementation thereof, including any 57 | amended or successor version of such directive); and 58 | 59 | vii. other similar, equivalent or corresponding rights throughout the world 60 | based on applicable law or treaty, and any national implementations thereof. 61 | 62 | 2. Waiver. To the greatest extent permitted by, but not in contravention of, 63 | applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and 64 | unconditionally waives, abandons, and surrenders all of Affirmer's Copyright 65 | and Related Rights and associated claims and causes of action, whether now 66 | known or unknown (including existing as well as future claims and causes of 67 | action), in the Work (i) in all territories worldwide, (ii) for the maximum 68 | duration provided by applicable law or treaty (including future time extensions), 69 | (iii) in any current or future medium and for any number of copies, and (iv) 70 | for any purpose whatsoever, including without limitation commercial, advertising 71 | or promotional purposes (the "Waiver"). Affirmer makes the Waiver for the 72 | benefit of each member of the public at large and to the detriment of Affirmer's 73 | heirs and successors, fully intending that such Waiver shall not be subject 74 | to revocation, rescission, cancellation, termination, or any other legal or 75 | equitable action to disrupt the quiet enjoyment of the Work by the public 76 | as contemplated by Affirmer's express Statement of Purpose. 77 | 78 | 3. Public License Fallback. Should any part of the Waiver for any reason be 79 | judged legally invalid or ineffective under applicable law, then the Waiver 80 | shall be preserved to the maximum extent permitted taking into account Affirmer's 81 | express Statement of Purpose. In addition, to the extent the Waiver is so 82 | judged Affirmer hereby grants to each affected person a royalty-free, non 83 | transferable, non sublicensable, non exclusive, irrevocable and unconditional 84 | license to exercise Affirmer's Copyright and Related Rights in the Work (i) 85 | in all territories worldwide, (ii) for the maximum duration provided by applicable 86 | law or treaty (including future time extensions), (iii) in any current or 87 | future medium and for any number of copies, and (iv) for any purpose whatsoever, 88 | including without limitation commercial, advertising or promotional purposes 89 | (the "License"). The License shall be deemed effective as of the date CC0 90 | was applied by Affirmer to the Work. Should any part of the License for any 91 | reason be judged legally invalid or ineffective under applicable law, such 92 | partial invalidity or ineffectiveness shall not invalidate the remainder of 93 | the License, and in such case Affirmer hereby affirms that he or she will 94 | not (i) exercise any of his or her remaining Copyright and Related Rights 95 | in the Work or (ii) assert any associated claims and causes of action with 96 | respect to the Work, in either case contrary to Affirmer's express Statement 97 | of Purpose. 98 | 99 | 4. Limitations and Disclaimers. 100 | 101 | a. No trademark or patent rights held by Affirmer are waived, abandoned, surrendered, 102 | licensed or otherwise affected by this document. 103 | 104 | b. Affirmer offers the Work as-is and makes no representations or warranties 105 | of any kind concerning the Work, express, implied, statutory or otherwise, 106 | including without limitation warranties of title, merchantability, fitness 107 | for a particular purpose, non infringement, or the absence of latent or other 108 | defects, accuracy, or the present or absence of errors, whether or not discoverable, 109 | all to the greatest extent permissible under applicable law. 110 | 111 | c. Affirmer disclaims responsibility for clearing rights of other persons 112 | that may apply to the Work or any use thereof, including without limitation 113 | any person's Copyright and Related Rights in the Work. Further, Affirmer disclaims 114 | responsibility for obtaining any necessary consents, permissions or other 115 | rights required for any use of the Work. 116 | 117 | d. Affirmer understands and acknowledges that Creative Commons is not a party 118 | to this document and has no duty or obligation with respect to this CC0 or 119 | use of the Work. 120 | -------------------------------------------------------------------------------- /3rdparty/wsdl/www.onvif.org/ver10/schema/common.xsd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | Pan/tilt coordinate space selector. The following options are defined:
    14 |
  • http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace
  • 15 |
  • http://www.onvif.org/ver10/tptz/PanTiltSpaces/TranslationGenericSpace
  • 16 |
  • http://www.onvif.org/ver10/tptz/PanTiltSpaces/VelocityGenericSpace
  • 17 |
  • http://www.onvif.org/ver10/tptz/PanTiltSpaces/GenericSpeedSpace
  • 18 |
19 |
20 |
21 |
22 |
23 | 24 | 25 | 26 | 27 | 28 | Zoom coordinate space selector. The following options are defined:
    29 |
  • http://www.onvif.org/ver10/tptz/ZoomSpaces/PositionGenericSpace
  • 30 |
  • http://www.onvif.org/ver10/tptz/ZoomSpaces/TranslationGenericSpace
  • 31 |
  • http://www.onvif.org/ver10/tptz/ZoomSpaces/VelocityGenericSpace
  • 32 |
  • http://www.onvif.org/ver10/tptz/ZoomSpaces/ZoomGenericSpeedSpace
  • 33 |
34 |
35 |
36 |
37 |
38 | 39 | 40 | 41 | 42 | Pan and tilt position. The x component corresponds to pan and the y component to tilt. 43 | 44 | 45 | 46 | 47 | 48 | A zoom position. 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | Specifies the absolute position of the PTZ unit together with the Space references. The default absolute spaces of the corresponding PTZ configuration MUST be referenced within the Position element. 60 | 61 | 62 | 63 | 64 | 65 | 66 | Indicates if the Pan/Tilt/Zoom device unit is currently moving, idle or in an unknown state. 67 | 68 | 69 | 70 | 71 | 72 | 73 | States a current PTZ error. 74 | 75 | 76 | 77 | 78 | 79 | 80 | Specifies the UTC time when this status was generated. 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 |
162 | --------------------------------------------------------------------------------