sample code - “control Monitoring”

usage:
   set <ipaddress of this pc> <0(Downtime ms)> <0(VideoPort)> <0(MetaPort)> <1~3(level)> <UDP|TCP>
   start  - monitoring start
   stop   - monitoring stop
   l      - get live view
To exit, please enter 'q'.
sample:
    set 192.168.11.4 0 0 0 1 UDP
This sample code is included in SimpleCli.
  1// "Monitoring" sample
  2#include <chrono>
  3#include <cstdint>
  4#include <cstdlib>
  5#include <fstream>
  6#include <future>
  7#include <iostream>
  8#include <mutex>
  9#include <sstream>
 10#include <stdexcept>
 11#include <string>
 12#include <thread>
 13#include <vector>
 14
 15#if !defined(__APPLE__)
 16  #if defined(USE_EXPERIMENTAL_FS) // for jetson
 17    #include <experimental/filesystem>
 18    namespace fs = std::experimental::filesystem;
 19  #else
 20    #include <filesystem>
 21    namespace fs = std::filesystem;
 22  #endif
 23#endif
 24
 25#if defined(__APPLE__) || defined(__linux__)
 26  #include <unistd.h>
 27#endif
 28
 29// macro for multibyte character
 30#if defined(_WIN32) || defined(_WIN64)
 31  using CrString = std::wstring;
 32  #define CRSTR(s) L ## s
 33  #define CrCout std::wcout
 34  #define DELIMITER CRSTR("\\")
 35#else
 36  using CrString = std::string;
 37  #define CRSTR(s) s
 38  #define CrCout std::cout
 39  #define DELIMITER CRSTR("/")
 40#endif
 41
 42
 43#include "CrDeviceProperty.h"
 44#include "CameraRemote_SDK.h"
 45#include "IDeviceCallback.h"
 46#include "CrDebugString.h"   // use CrDebugString.cpp
 47
 48#define PrintError(msg, err) { fprintf(stderr, "Error in %s(%d):" msg ",%s\n", __FUNCTION__, __LINE__, (err ? CrErrorString(err).c_str():"")); }
 49#define GotoError(msg, err) { PrintError(msg, err); goto Error; }
 50
 51bool  m_connected = false;
 52CrString m_modelId;
 53int64_t  m_device_handle = 0;
 54
 55std::mutex m_eventPromiseMutex;
 56uint32_t m_setDPCode = 0;
 57std::promise<void>* m_eventPromise = nullptr;
 58void setEventPromise(std::promise<void>* dp)
 59{
 60    std::lock_guard<std::mutex> lock(m_eventPromiseMutex);
 61    m_eventPromise = dp;
 62}
 63
 64SCRSDK::CrError _getDeviceProperty(int64_t device_handle, uint32_t code, SCRSDK::CrDeviceProperty* devProp)
 65{
 66    std::int32_t nprop = 0;
 67    SCRSDK::CrDeviceProperty* prop_list = nullptr;
 68    SCRSDK::CrError err = SCRSDK::GetSelectDeviceProperties(device_handle, 1, &code, &prop_list, &nprop);
 69    if(err) GotoError("", err);
 70    if(prop_list && nprop >= 1) {
 71        *devProp = prop_list[0];
 72    }
 73Error:
 74    if(prop_list) SCRSDK::ReleaseDeviceProperties(device_handle, prop_list);
 75    return err;
 76}
 77
 78class DeviceCallback : public SCRSDK::IDeviceCallback
 79{
 80public:
 81    DeviceCallback() {};
 82    ~DeviceCallback() {};
 83
 84    void OnConnected(SCRSDK::DeviceConnectionVersioin version)
 85    {
 86        CrCout << "Connected to " << m_modelId << "\n";
 87        m_connected = true;
 88        std::lock_guard<std::mutex> lock(m_eventPromiseMutex);
 89        if(m_eventPromise) {
 90            m_eventPromise->set_value();
 91            m_eventPromise = nullptr;
 92        }
 93    }
 94
 95    void OnError(CrInt32u error)
 96    {
 97        printf("Connection error:%s\n", CrErrorString(error).c_str());
 98        std::lock_guard<std::mutex> lock(m_eventPromiseMutex);
 99        if(m_eventPromise) {
100            m_eventPromise->set_exception(std::make_exception_ptr(std::runtime_error("error")));
101            m_eventPromise = nullptr;
102        }
103    }
104
105    void OnDisconnected(CrInt32u error)
106    {
107        CrCout << "Disconnected from " << m_modelId << "\n";
108        m_connected = false;
109        std::lock_guard<std::mutex> lock(m_eventPromiseMutex);
110        if(m_eventPromise) {
111            m_eventPromise->set_value();
112            m_eventPromise = nullptr;
113        }
114    }
115
116    void OnCompleteDownload(CrChar* filename, CrInt32u type )
117    {
118        CrCout << "OnCompleteDownload:" << filename << "\n";
119    }
120
121    void OnNotifyContentsTransfer(CrInt32u notify, SCRSDK::CrContentHandle contentHandle, CrChar* filename)
122    {
123        std::cout << "OnNotifyContentsTransfer.\n";
124    }
125
126    void OnWarning(CrInt32u warning)
127    {
128        if (warning == SCRSDK::CrWarning_Connect_Reconnecting) {
129            CrCout << "Reconnecting to " << m_modelId << "\n";
130            return;
131        }
132        std::cout << "OnWarning:" << CrErrorString(warning) << "\n";
133    }
134
135    void OnWarningExt(CrInt32u warning, CrInt32 param1, CrInt32 param2, CrInt32 param3)
136    {
137        std::cout << "OnWarningExt:" << CrWarningExtString(warning, param1, param2, param3).c_str() << "\n";
138    }
139
140    void OnLvPropertyChanged() {}
141    void OnLvPropertyChangedCodes(CrInt32u num, CrInt32u* codes) {}
142    void OnPropertyChanged() {}
143    void OnPropertyChangedCodes(CrInt32u num, CrInt32u* codes)
144    {
145        std::cout << "OnPropertyChangedCodes:\n";
146        for(uint32_t i = 0; i < num; ++i) {
147            switch(codes[i]) {
148                case SCRSDK::CrDeviceProperty_MonitoringIsDelivering: {
149                    std::string name = CrDevicePropertyString((SCRSDK::CrDevicePropertyCode)codes[i]);
150                    SCRSDK::CrDeviceProperty devProp;
151                    SCRSDK::CrError err = _getDeviceProperty(m_device_handle, codes[i], &devProp);
152                    if(!err) {
153                        printf("  %s=%d\n", name.c_str(), (int)devProp.GetCurrentValue());
154                    }
155                }
156                break;
157            }
158        }
159    }
160};
161
162CrString _getModelId(const SCRSDK::ICrCameraObjectInfo* objInfo)
163{
164    CrString id;
165    if (CrString(objInfo->GetConnectionTypeName()) == CRSTR("IP")) {
166        id = CrString(objInfo->GetMACAddressChar());
167    } else {
168        id = CrString((CrChar*)objInfo->GetId());
169    }
170    return CrString(objInfo->GetModel()).append(CRSTR(" (")).append(id).append(CRSTR(")"));
171}
172
173SCRSDK::CrError _getIdPassword(SCRSDK::ICrCameraObjectInfo* objInfo, std::string& fingerprint, std::string& userId, std::string& userPassword)
174{
175    char fpBuff[128] = {0};
176    CrInt32u fpLen = 0;
177    SCRSDK::CrError err = SCRSDK::GetFingerprint(objInfo, fpBuff, &fpLen);
178    if(err) GotoError("", err);
179    fingerprint = std::string(fpBuff, fpLen);
180
181    std::cout << "fingerprint: " << fingerprint.c_str() << "\n";
182    std::cout << "id:";       std::getline(std::cin, userId);
183    std::cout << "password:"; std::getline(std::cin, userPassword);
184    return 0;
185Error:
186    return err;
187}
188
189std::vector<std::string> _split(std::string inputLine, char delimiter)
190{
191    std::vector<std::string> strArray;
192    if (inputLine.empty()) return strArray;
193
194    std::string tmp;
195    std::stringstream ss{inputLine};
196    while (getline(ss, tmp, delimiter)) {
197        strArray.push_back(tmp);
198    }
199    return strArray;
200}
201
202SCRSDK::CrError _setMonitoringDeriverySetting(int64_t device_handle, std::vector<std::string>& args)
203{
204    // "set <ipaddress of this pc> <0(Downtime ms)> <0(VideoPort)> <0(MetaPort)> <1~3(level)> <UDP|TCP>";
205
206    SCRSDK::CrError err = SCRSDK::CrError_Generic_Unknown;
207    SCRSDK::CrMonitoringDeliverySetting setting;
208    int deliveryImageQualityLevel = 0;
209
210    setting.type = SCRSDK::CrMonitoringDeliveryType_Jpeg;
211    setting.SetIpAddress(args[1].c_str());
212    try { setting.downTime = stoi(args[2]); } catch(const std::exception&) { GotoError("", 0); }
213    try { setting.videoPort = stoi(args[3]); } catch(const std::exception&) { GotoError("", 0); }
214    try { setting.metaPort = stoi(args[4]); } catch(const std::exception&) { GotoError("", 0); }
215
216    try { deliveryImageQualityLevel = stoi(args[5]); } catch(const std::exception&) { GotoError("", 0); }
217    if (deliveryImageQualityLevel < 1 || deliveryImageQualityLevel > 3) GotoError("", 0);
218    setting.deliveryImageQualityLevel = (SCRSDK::CrMonitoringFormat_DeliveryImageQualityLevel)deliveryImageQualityLevel;
219
220    if      (args[6] == "UDP") setting.transportProtocol = SCRSDK::CrMonitoringTransportProtocol_UDP;
221    else if (args[6] == "TCP") setting.transportProtocol = SCRSDK::CrMonitoringTransportProtocol_TCP;
222    else GotoError("", 0);
223
224    err = SCRSDK::SetMonitoringDeliverySetting(device_handle, &setting, 1);
225    if(err) GotoError("", err);
226Error:
227    return err;
228}
229
230SCRSDK::CrError _getLiveView(int64_t device_handle, CrString path)
231{
232    int result = SCRSDK::CrError_Generic_Unknown;
233    SCRSDK::CrError err = 0;
234    CrInt32 num = 0;
235    SCRSDK::CrLiveViewProperty* property = nullptr;
236    SCRSDK::CrImageInfo imageInfo;
237    SCRSDK::CrImageDataBlock image_data;
238    CrInt32u bufSize = 0;
239    CrInt8u* image_buff = nullptr;
240
241    err = SCRSDK::GetLiveViewProperties(device_handle, &property, &num);  if(err) GotoError("", err);
242    SCRSDK::ReleaseLiveViewProperties(device_handle, property);
243
244    err = SCRSDK::GetLiveViewImageInfo(device_handle, &imageInfo);  if(err) GotoError("", err);
245    bufSize = imageInfo.GetBufferSize();
246    if (bufSize <= 0) GotoError("", 0);
247
248    image_buff = new CrInt8u[bufSize];
249    if (!image_buff) GotoError("", 0);
250
251    image_data.SetData(image_buff);
252    image_data.SetSize(bufSize);
253
254    err = SCRSDK::GetLiveViewImage(device_handle, &image_data);  if(err) GotoError("", err);
255    if (image_data.GetSize() <= 0) GotoError("", 0);
256
257    {
258        path.append(DELIMITER CRSTR("LiveView000000.JPG"));
259        std::ofstream file(path, std::ios::out | std::ios::binary);
260        if (file.bad()) GotoError("", 0);
261        file.write((char*)image_data.GetImageData(), image_data.GetImageSize());
262        file.close();
263        CrCout << path.data() << '\n';
264    }
265    result = 0;
266Error:
267    if(image_buff) delete[] image_buff;
268    return result;
269}
270
271int main(void)
272{
273    int result = -1;
274    SCRSDK::CrError err = SCRSDK::CrError_None;
275    SCRSDK::ICrEnumCameraObjectInfo* enumCameraObjectInfo = nullptr;
276    SCRSDK::ICrCameraObjectInfo* objInfo = nullptr;
277    DeviceCallback deviceCallback;
278
279  #if defined(__APPLE__)
280    #define MAC_MAX_PATH 255
281    char pathBuf[MAC_MAX_PATH] = {0};
282    if(NULL == getcwd(pathBuf, sizeof(pathBuf) - 1)) return 1;
283    CrString path = pathBuf;
284  #else
285    CrString path = fs::current_path().native();
286  #endif
287
288    bool boolRet = SCRSDK::Init();
289    if(!boolRet) GotoError("", 0);
290
291    // enumeration
292    {
293        uint32_t count = 0;
294        uint32_t index = 1;
295
296        err = SCRSDK::EnumCameraObjects(&enumCameraObjectInfo, 3/*timeInSec*/);
297        if(err || !enumCameraObjectInfo) GotoError("no camera", err);
298
299        count = enumCameraObjectInfo->GetCount();
300        if(count >= 2) {
301            for (uint32_t i = 0; i < count; ++i) {
302                auto* info = enumCameraObjectInfo->GetCameraObjectInfo(i);
303                CrCout << '[' << i + 1 << "] " << _getModelId(info) << "\n";
304            }
305
306            std::string inputLine;
307            std::cout << "select camera:"; std::getline(std::cin, inputLine);
308            try { index = stoi(inputLine); } catch(const std::exception&) { GotoError("", 0); }
309            if(index < 1 || index > count) GotoError("", 0);
310        }
311        objInfo = (SCRSDK::ICrCameraObjectInfo*)enumCameraObjectInfo->GetCameraObjectInfo(index - 1);
312        m_modelId = _getModelId(objInfo);
313    }
314
315    // connect
316    {
317        std::string  fingerprint = "";
318        std::string  userId = "";
319        std::string  userPassword = "";
320        std::promise<void> eventPromise;
321        std::future<void> eventFuture = eventPromise.get_future();
322
323        if (objInfo->GetSSHsupport() == SCRSDK::CrSSHsupport_ON) {
324            err = _getIdPassword(objInfo, fingerprint, userId, userPassword); if(err) goto Error;
325        }
326
327        setEventPromise(&eventPromise);
328        err = SCRSDK::Connect(objInfo, &deviceCallback, &m_device_handle,
329            SCRSDK::CrSdkControlMode_Remote,
330            SCRSDK::CrReconnecting_ON,
331            userId.c_str(), userPassword.c_str(), fingerprint.c_str(), (uint32_t)fingerprint.size());
332        if(err) GotoError("", err);
333
334    //  std::future_status status = eventFuture.wait_for(std::chrono::milliseconds(3000));
335    //  if(status != std::future_status::ready) GotoError("timeout",0);
336        try{
337            eventFuture.get();
338        } catch(const std::exception&) GotoError("", 0);
339    }
340
341    // set work directory
342    {
343        CrCout << "path=" << path.data() << "\n";
344        err = SCRSDK::SetSaveInfo(m_device_handle, const_cast<CrChar*>(path.data()), const_cast<CrChar*>(CRSTR("DSC")), -1/*startNo*/);
345        if(err) GotoError("", err);
346    }
347
348    std::this_thread::sleep_for(std::chrono::milliseconds(1000));
349
350    std::cout << "usage:\n";
351    std::cout << "   set <ipaddress of this pc> <0(Downtime ms)> <0(VideoPort)> <0(MetaPort)> <1~3(level)> <UDP|TCP>\n";
352    std::cout << "   start  - monitoring start\n";
353    std::cout << "   stop   - monitoring stop\n";
354    std::cout << "   l      - get live view\n";
355    std::cout << "To exit, please enter 'q'.\n";
356
357    while(1) {
358        std::string inputLine;
359        std::getline(std::cin, inputLine);
360        std::vector<std::string> args = _split(inputLine, ' ');
361
362        if(args.size() == 0) {
363
364        } else if(args[0] == "set" && args.size() >= 7) {
365            err = _setMonitoringDeriverySetting(m_device_handle, args);
366            if(err) goto Error;
367
368        } else if(args[0] == "start") {
369            err = SCRSDK::ControlMonitoring(m_device_handle, SCRSDK::CrMonitoringOperation_Start);
370            if(err) GotoError("", err);
371
372        } else if(args[0] == "stop") {
373            err = SCRSDK::ControlMonitoring(m_device_handle, SCRSDK::CrMonitoringOperation_Stop);
374            if(err) GotoError("", err);
375
376        } else if(args[0] == "l" || args[0] == "L") {
377            err = _getLiveView(m_device_handle, path);
378            if(err) goto Error;
379
380        } else if(args[0] == "q" || args[0] == "Q") {
381            break;
382        } else {
383            std::cout << "unknown command\n";
384        }
385    }
386
387    result = 0;
388Error:
389    if(enumCameraObjectInfo) enumCameraObjectInfo->Release();
390
391    if(m_connected) {
392        std::promise<void> eventPromise;
393        std::future<void> eventFuture = eventPromise.get_future();
394        setEventPromise(&eventPromise);
395        SCRSDK::Disconnect(m_device_handle);
396        eventFuture.wait_for(std::chrono::milliseconds(3000));
397    }
398    if(m_device_handle) SCRSDK::ReleaseDevice(m_device_handle);
399    SCRSDK::Release();
400
401    return result;
402}