sample code - “pull/delete/playback content in RemoteTransferMode”¶
usage:
s [1~2(slot)] - Select content
g [0(content),1(thumbnail),2(screennail)] - Get content
d - Delete content
ip <192.168.1.2(ip of this PC)> - set ip of this PC
p [1(start),2(stop),4(resume),5(pause),6(seek)] - Playback content
postview <1(enable),0(disable)> <0(legacy),0x8000(file),0x8001(ram)>
pull
To exit, please enter 'q'.
“Playback content” exports elementary streams to temp.hevc and temp.aac. Please MUX them by using a tool such as ffmpeg.
example:
ffmpeg -i temp.hevc -i temp.aac -c copy output.mp4
This sample code is included in SimpleCli.
For Linux environment, “export LD_LIBRARY_PATH=xx” is necessary
1// "pull/delete/playback contents in RemoteTransferMode" 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 CrPrintf std::wprintf
35 #define DELIMITER CRSTR("\\")
36#else
37 using CrString = std::string;
38 #define CRSTR(s) s
39 #define CrCout std::cout
40 #define CrPrintf std::printf
41 #define DELIMITER CRSTR("/")
42#endif
43
44
45#include "CrDeviceProperty.h"
46#include "CameraRemote_SDK.h"
47#include "IDeviceCallback.h"
48#include "CrDebugString.h" // use CrDebugString.cpp
49
50#define PrintError(msg, err) { fprintf(stderr, "Error in %s(%d):" msg ",%s\n", __FUNCTION__, __LINE__, (err ? CrErrorString(err).c_str():"")); }
51#define GotoError(msg, err) { PrintError(msg, err); goto Error; }
52
53bool m_connected = false;
54CrString m_modelId;
55int64_t m_device_handle = 0;
56uint32_t m_postview_size = 0;
57CrString m_postview_filename = CRSTR("");
58
59std::mutex m_eventPromiseMutex;
60uint32_t m_setDPCode = 0;
61std::promise<void>* m_eventPromise = nullptr;
62void setEventPromise(std::promise<void>* dp)
63{
64 std::lock_guard<std::mutex> lock(m_eventPromiseMutex);
65 m_eventPromise = dp;
66}
67
68std::ofstream* m_fileVideo = nullptr;
69std::ofstream* m_fileAudio = nullptr;
70
71SCRSDK::CrError _getDeviceProperty(int64_t device_handle, uint32_t code, SCRSDK::CrDeviceProperty* devProp)
72{
73 std::int32_t nprop = 0;
74 SCRSDK::CrDeviceProperty* prop_list = nullptr;
75 SCRSDK::CrError err = SCRSDK::GetSelectDeviceProperties(device_handle, 1, &code, &prop_list, &nprop);
76 if(err) GotoError("", err);
77 if(prop_list && nprop >= 1) {
78 *devProp = prop_list[0];
79 }
80Error:
81 if(prop_list) SCRSDK::ReleaseDeviceProperties(device_handle, prop_list);
82 return err;
83}
84
85class DeviceCallback : public SCRSDK::IDeviceCallback
86{
87public:
88 DeviceCallback() {};
89 ~DeviceCallback() {};
90
91 void OnConnected(SCRSDK::DeviceConnectionVersioin version)
92 {
93 CrCout << "Connected to " << m_modelId << "\n";
94 m_connected = true;
95 std::lock_guard<std::mutex> lock(m_eventPromiseMutex);
96 if(m_eventPromise) {
97 m_eventPromise->set_value();
98 m_eventPromise = nullptr;
99 }
100 }
101
102 void OnError(CrInt32u error)
103 {
104 printf("Connection error:%s\n", CrErrorString(error).c_str());
105 std::lock_guard<std::mutex> lock(m_eventPromiseMutex);
106 if(m_eventPromise) {
107 m_eventPromise->set_exception(std::make_exception_ptr(std::runtime_error("error")));
108 m_eventPromise = nullptr;
109 }
110 }
111
112 void OnDisconnected(CrInt32u error)
113 {
114 CrCout << "Disconnected from " << m_modelId << "\n";
115 m_connected = false;
116 std::lock_guard<std::mutex> lock(m_eventPromiseMutex);
117 if(m_eventPromise) {
118 m_eventPromise->set_value();
119 m_eventPromise = nullptr;
120 }
121 }
122
123 void OnCompleteDownload(CrChar* filename, CrInt32u type )
124 {
125 CrCout << "OnCompleteDownload:" << filename << "\n";
126 }
127
128 void OnNotifyPostViewImage(CrChar* filename, CrInt32u size)
129 {
130 CrCout << "OnNotifyPostViewImage:" << filename << "," << size << "\n";
131 m_postview_size = size;
132 m_postview_filename = filename;
133 }
134
135 void OnNotifyContentsTransfer(CrInt32u notify, SCRSDK::CrContentHandle contentHandle, CrChar* filename)
136 {
137 std::cout << "OnNotifyContentsTransfer:" << CrErrorString(notify) << "\n";
138 }
139
140 void OnNotifyRemoteTransferResult(CrInt32u notify, CrInt32u per, CrChar* filename)
141 {
142 std::cout << "OnNotifyRemoteTransferResult:" << CrErrorString(notify) << "\n";
143 std::lock_guard<std::mutex> lock(m_eventPromiseMutex);
144 switch(notify) {
145 case SCRSDK::CrNotify_RemoteTransfer_Result_OK:
146 CrCout << filename << "\n";
147 if(m_eventPromise) {
148 m_eventPromise->set_value();
149 m_eventPromise = nullptr;
150 }
151 break;
152 case SCRSDK::CrNotify_RemoteTransfer_Result_NG:
153 case SCRSDK::CrNotify_RemoteTransfer_Result_DeviceBusy:
154 if(m_eventPromise) {
155 m_eventPromise->set_exception(std::make_exception_ptr(std::runtime_error("error")));
156 m_eventPromise = nullptr;
157 }
158 break;
159 }
160 }
161
162 void OnNotifyRemoteTransferResult(CrInt32u notify, CrInt32u per, CrInt8u* data, CrInt64u size)
163 {
164 std::cout << "OnNotifyRemoteTransferResult xx:" << CrErrorString(notify) << "\n";
165 std::lock_guard<std::mutex> lock(m_eventPromiseMutex);
166 if(m_eventPromise) {
167 m_eventPromise->set_value();
168 m_eventPromise = nullptr;
169 }
170 }
171
172 void OnNotifyRemoteTransferContentsListChanged(CrInt32u notify, CrInt32u slotNumber, CrInt32u addSize)
173 {
174 std::cout << "OnNotifyRemoteTransferContentsListChanged:" << CrErrorString(notify) << "\n";
175 }
176
177 void OnReceivePlaybackData(CrInt8u mediaType, CrInt32 dataSize, CrInt8u* data, CrInt64 pts, CrInt64 dts, CrInt32 param1, CrInt32 param2)
178 {
179 // std::cout << "OnReceivePlaybackData:\n";
180 switch(mediaType) {
181 case SCRSDK::CrMoviePlaybackDataType_Video:
182 if(m_fileVideo) m_fileVideo->write((char*)data, dataSize);
183 break;
184 case SCRSDK::CrMoviePlaybackDataType_Audio:
185 if(m_fileAudio) m_fileAudio->write((char*)data, dataSize);
186 break;
187 }
188 }
189 void OnReceivePlaybackTimeCode(CrInt32u timeCode)
190 {
191 // printf("OnReceivePlaybackTimeCode:%d\n", timeCode);
192 }
193
194 void OnWarning(CrInt32u warning)
195 {
196 if (warning == SCRSDK::CrWarning_Connect_Reconnecting) {
197 CrCout << "Reconnecting to " << m_modelId << "\n";
198 return;
199 }
200 std::cout << "OnWarning:" << CrErrorString(warning) << "\n";
201 std::lock_guard<std::mutex> lock(m_eventPromiseMutex);
202 switch(warning) {
203 case SCRSDK::CrNotify_Playback_Result_StopComplete:
204 if(m_fileVideo) {
205 m_fileVideo->close();
206 m_fileVideo = nullptr;
207 }
208 if(m_fileAudio) {
209 m_fileAudio->close();
210 m_fileAudio = nullptr;
211 }
212 [[fallthrough]];
213 case SCRSDK::CrNotify_Playback_StatusChanged:
214 if(m_eventPromise) {
215 m_eventPromise->set_value();
216 m_eventPromise = nullptr;
217 }
218 break;
219
220 case SCRSDK::CrNotify_Playback_Result_NormalTermination:
221 SCRSDK::ControlMoviePlayback(m_device_handle, SCRSDK::CrMoviePlaybackControlType_Stop, 0);
222 break;
223
224 case SCRSDK::CrWarning_Playback_Result_Invalid:
225 case SCRSDK::CrWarning_Playback_Result_CameraOperateTermination:
226 case SCRSDK::CrWarning_Playback_Result_SystemError:
227 case SCRSDK::CrWarning_Playback_Result_HighTemperature:
228 case SCRSDK::CrWarning_Playback_Result_MediaRemoval:
229 case SCRSDK::CrWarning_Playback_Result_ContentsError:
230 case SCRSDK::CrWarning_Playback_Result_KeepAliveTimeout:
231 case SCRSDK::CrWarning_Playback_Result_Start_Fail:
232 case SCRSDK::CrWarning_Playback_Result_Stop_Fail:
233 case SCRSDK::CrWarning_Playback_Result_Play_Fail:
234 case SCRSDK::CrWarning_Playback_Result_Pause_Fail:
235 if(m_eventPromise) {
236 m_eventPromise->set_exception(std::make_exception_ptr(std::runtime_error("error")));
237 m_eventPromise = nullptr;
238 }
239 break;
240/*
241 case SCRSDK::CrNotify_Playback_Result_PlaybackInfo_Success:
242 case SCRSDK::CrWarning_Playback_Result_PlaybackInfo_Error:
243*/
244 }
245 }
246
247 void OnWarningExt(CrInt32u warning, CrInt32 param1, CrInt32 param2, CrInt32 param3)
248 {
249 std::cout << "OnWarningExt:" << CrWarningExtString(warning, param1, param2, param3).c_str() << "\n";
250 if(warning == SCRSDK::CrWarningExt_DeleteContent) {
251 std::lock_guard<std::mutex> lock(m_eventPromiseMutex);
252 switch(param1) {
253 case SCRSDK::CrWarningExtParam_DeleteContentResult_OK:
254 if(m_eventPromise) {
255 m_eventPromise->set_value();
256 m_eventPromise = nullptr;
257 }
258 break;
259 default:
260 if(m_eventPromise) {
261 m_eventPromise->set_exception(std::make_exception_ptr(std::runtime_error("error")));
262 m_eventPromise = nullptr;
263 }
264 break;
265 }
266 }
267 }
268 void OnLvPropertyChanged() {}
269 void OnLvPropertyChangedCodes(CrInt32u num, CrInt32u* codes) {}
270 void OnPropertyChanged() {}
271 void OnPropertyChangedCodes(CrInt32u num, CrInt32u* codes)
272 {
273 for(uint32_t i = 0; i < num; ++i) {
274 if(codes[i] == SCRSDK::CrDeviceProperty_PullPostViewImageStatus) {
275 SCRSDK::CrDeviceProperty devProp;
276 SCRSDK::CrError err = _getDeviceProperty(m_device_handle, SCRSDK::CrDeviceProperty_PullPostViewImageStatus, &devProp);
277 if(!err) {
278 std::cout << "OnPropertyChangedCodes:PullPostViewImageStatus=" << (devProp.GetCurrentValue() ? "Exists" : "Not Exists") << "\n";
279 }
280 }
281 }
282 }
283};
284
285CrString _getModelId(const SCRSDK::ICrCameraObjectInfo* objInfo)
286{
287 CrString id;
288 if (CrString(objInfo->GetConnectionTypeName()) == CRSTR("IP")) {
289 id = CrString(objInfo->GetMACAddressChar());
290 } else {
291 id = CrString((CrChar*)objInfo->GetId());
292 }
293 return CrString(objInfo->GetModel()).append(CRSTR(" (")).append(id).append(CRSTR(")"));
294}
295
296SCRSDK::CrError _getIdPassword(SCRSDK::ICrCameraObjectInfo* objInfo, std::string& fingerprint, std::string& userId, std::string& userPassword)
297{
298 char fpBuff[128] = {0};
299 CrInt32u fpLen = 0;
300 SCRSDK::CrError err = SCRSDK::GetFingerprint(objInfo, fpBuff, &fpLen);
301 if(err) GotoError("", err);
302 fingerprint = std::string(fpBuff, fpLen);
303
304 std::cout << "fingerprint: " << fingerprint.c_str() << "\n";
305 std::cout << "id:"; std::getline(std::cin, userId);
306 std::cout << "password:"; std::getline(std::cin, userPassword);
307 return 0;
308Error:
309 return err;
310}
311
312SCRSDK::CrError _shooting(int64_t device_handle)
313{
314 SCRSDK::CrError err = 0;
315
316 err = SCRSDK::SendCommand(device_handle, SCRSDK::CrCommandId_Release, SCRSDK::CrCommandParam_Down); if (err) GotoError("", err);
317 std::this_thread::sleep_for(std::chrono::milliseconds(35));
318 err = SCRSDK::SendCommand(device_handle, SCRSDK::CrCommandId_Release, SCRSDK::CrCommandParam_Up); if (err) GotoError("", err);
319
320 std::cout << "OK\n";
321Error:
322 return err;
323}
324
325void _showContentsInfo(SCRSDK::CrContentsInfo& contentsInfo)
326{
327 std::cout << "\n";
328 std::cout << "[ContentsInfo]\n";
329 printf("contentType = %d\n", contentsInfo.contentType);
330 printf("contentId = %u\n", contentsInfo.contentId);
331 printf("dirNumber = %u\n", contentsInfo.dirNumber);
332 printf("fileNumber = %u\n", contentsInfo.fileNumber);
333 printf("groupType = %d\n", contentsInfo.groupType);
334 printf("representative = %u\n", contentsInfo.representative);
335 printf("creationDatetimeUTC = %04d/%02d/%02d %02d:%02d:%02d.%03d\n",
336 contentsInfo.creationDatetimeUTC.year,
337 contentsInfo.creationDatetimeUTC.month,
338 contentsInfo.creationDatetimeUTC.day,
339 contentsInfo.creationDatetimeUTC.hour,
340 contentsInfo.creationDatetimeUTC.minute,
341 contentsInfo.creationDatetimeUTC.sec,
342 contentsInfo.creationDatetimeUTC.msec);
343 printf("modificationDatetimeUTC = %04d/%02d/%02d %02d:%02d:%02d.%03d\n",
344 contentsInfo.modificationDatetimeUTC.year,
345 contentsInfo.modificationDatetimeUTC.month,
346 contentsInfo.modificationDatetimeUTC.day,
347 contentsInfo.modificationDatetimeUTC.hour,
348 contentsInfo.modificationDatetimeUTC.minute,
349 contentsInfo.modificationDatetimeUTC.sec,
350 contentsInfo.modificationDatetimeUTC.msec);
351 printf("creationDatetimeLocaltime = %04d/%02d/%02d %02d:%02d:%02d.%03d\n",
352 contentsInfo.creationDatetimeLocaltime.year,
353 contentsInfo.creationDatetimeLocaltime.month,
354 contentsInfo.creationDatetimeLocaltime.day,
355 contentsInfo.creationDatetimeLocaltime.hour,
356 contentsInfo.creationDatetimeLocaltime.minute,
357 contentsInfo.creationDatetimeLocaltime.sec,
358 contentsInfo.creationDatetimeLocaltime.msec);
359 printf("modificationDatetimeLocaltime = %04d/%02d/%02d %02d:%02d:%02d.%03d\n",
360 contentsInfo.modificationDatetimeLocaltime.year,
361 contentsInfo.modificationDatetimeLocaltime.month,
362 contentsInfo.modificationDatetimeLocaltime.day,
363 contentsInfo.modificationDatetimeLocaltime.hour,
364 contentsInfo.modificationDatetimeLocaltime.minute,
365 contentsInfo.modificationDatetimeLocaltime.sec,
366 contentsInfo.modificationDatetimeLocaltime.msec);
367 printf("rating = %d\n", contentsInfo.rating);
368 printf("protectionStatus = %u\n", contentsInfo.protectionStatus);
369 printf("dummyContent = %u\n", contentsInfo.dummyContent);
370 printf("shotMarkNum = %u\n", contentsInfo.shotMarkNum);
371 for(CrInt32u i = 0; i < contentsInfo.shotMarkNum; i++) {
372 printf("No:%d, shotMark = %u\n",(i+1), contentsInfo.shotMark[i]);
373 }
374 printf("filesNum = %u\n", contentsInfo.filesNum);
375}
376
377void _showContentsFile(SCRSDK::CrContentsFile& contentsFile)
378{
379 printf("fileId = %u\n", contentsFile.fileId);
380 printf("filePathLength = %u\n", contentsFile.filePathLength);
381 if( contentsFile.filePathLength > 0 ) {
382 printf("filePath = %s\n", contentsFile.filePath);
383 }
384 printf("fileFormat = %u\n", contentsFile.fileFormat);
385 printf("fileSize = %d\n", (int)contentsFile.fileSize);
386 std::cout << "umid = 0x";
387 for(int j = 0; j < sizeof(contentsFile.umid); j++) {
388 printf("%02x", contentsFile.umid[j]);
389 }
390 std::cout << "\n";
391
392 printf("isImageParamExsist = %u\n", contentsFile.isImageParamExsist);
393 if( contentsFile.isImageParamExsist == true ) {
394 printf("imagePixWidth = %u\n", contentsFile.imageParam.imagePixWidth);
395 printf("imagePixHeight = %u\n", contentsFile.imageParam.imagePixHeight);
396 }
397
398 printf("isVideoParamExsist = %u\n", contentsFile.isVideoParamExsist);
399 if( contentsFile.isVideoParamExsist == true ) {
400 printf("startTimeCode = %u\n", contentsFile.videoParam.startTimeCode);
401 printf("endTimeCode = %u\n", contentsFile.videoParam.endTimeCode);
402 printf("videoCodec = %d\n", contentsFile.videoParam.videoCodec);
403 printf("proxyStatus = %u\n", contentsFile.videoParam.proxyStatus);
404 printf("gopStructure = %d\n", contentsFile.videoParam.gopStructure);
405 printf("width = %u\n", contentsFile.videoParam.width);
406 printf("height = %u\n", contentsFile.videoParam.height);
407 printf("aspectRatio = %d\n", contentsFile.videoParam.aspectRatio);
408 printf("colorFormat = %d\n", contentsFile.videoParam.colorFormat);
409 printf("imageBitDepth = %u\n", contentsFile.videoParam.imageBitDepth);
410 printf("framesPerThousandSeconds = %u\n", contentsFile.videoParam.framesPerThousandSeconds);
411 printf("scanType = %d\n", contentsFile.videoParam.scanType);
412 printf("bitrateMbps = %u\n", contentsFile.videoParam.bitrateMbps);
413 printf("imageFramesPerThousandSeconds = %u\n", contentsFile.videoParam.imageFramesPerThousandSeconds);
414 printf("profileIndication = %d\n", contentsFile.videoParam.profileIndication);
415 printf("profileLevel = %u\n", contentsFile.videoParam.profileLevel);
416 printf("rdd18metaCaptureGammaEquation = %d\n", contentsFile.videoParam.rdd18metaCaptureGammaEquation);
417 printf("rdd18metaColorPrimaries = %d\n", contentsFile.videoParam.rdd18metaColorPrimaries);
418 printf("rdd18metaCodingEquations = %d\n", contentsFile.videoParam.rdd18metaCodingEquations);
419 }
420
421 printf("isAudioParamExsist = %u\n", contentsFile.isAudioParamExsist);
422 if( contentsFile.isAudioParamExsist == true ) {
423 printf("audioCodec = %d\n", contentsFile.audioParam.audioCodec);
424 printf("audioBitDepth = %u\n", contentsFile.audioParam.audioBitDepth);
425 printf("samplingRate = %u\n", contentsFile.audioParam.samplingRate);
426 printf("numberOfChannels = %d\n", contentsFile.audioParam.numberOfChannels);
427 }
428 std::cout << "\n";
429}
430
431SCRSDK::CrError _selectContent(int64_t device_handle, SCRSDK::CrSlotNumber slotNumber, CrInt32u& contentId, CrInt32u& fileId)
432{
433 int result = SCRSDK::CrError_Generic_Unknown;
434 SCRSDK::CrError err = SCRSDK::CrError_None;
435 int index = 0;
436
437 SCRSDK::CrCaptureDate* m_captureDateList = nullptr;
438 SCRSDK::CrContentsInfo* m_contentsInfoList = nullptr;
439 std::string inputLine;
440 CrInt32u outNums = 0;
441
442 SCRSDK::CrContentsInfo contentsInfo;
443 SCRSDK::CrContentsFile contentsFile;
444
445 // select date
446 err = SCRSDK::GetRemoteTransferCapturedDateList(device_handle, slotNumber, &m_captureDateList, &outNums);
447 if(err || outNums == 0) GotoError("", err);
448
449 for(CrInt32u i = 0; i < outNums; i++) {
450 printf("[%d] %04d/%02d/%02d\n",(int)i, m_captureDateList[i].year, m_captureDateList[i].month, m_captureDateList[i].day);
451 }
452
453 std::cout << "date(0~ ):"; std::getline(std::cin, inputLine);
454 try { index = stoi(inputLine); } catch(const std::exception&) { GotoError("", 0); }
455 if(index < 0 || index >= (int)outNums) GotoError("", 0);
456
457 // select content
458 err = SCRSDK::GetRemoteTransferContentsInfoList(device_handle, slotNumber, SCRSDK::CrGetContentsInfoListType_Range_Day,
459 &m_captureDateList[index], /*maxNums*/0,
460 &m_contentsInfoList, &outNums);
461 if(err) GotoError("", err);
462
463 for(CrInt32u i = 0;i < outNums; i++) {
464 printf("[%d] %04d/%02d/%02d %02d:%02d:%02d, FileName:%s\n", i,
465 m_contentsInfoList[i].creationDatetimeLocaltime.year,
466 m_contentsInfoList[i].creationDatetimeLocaltime.month,
467 m_contentsInfoList[i].creationDatetimeLocaltime.day,
468 m_contentsInfoList[i].creationDatetimeLocaltime.hour,
469 m_contentsInfoList[i].creationDatetimeLocaltime.minute,
470 m_contentsInfoList[i].creationDatetimeLocaltime.sec,
471 m_contentsInfoList[i].files[0].filePath);
472 }
473
474 std::cout << "index(0~ ):"; std::getline(std::cin, inputLine);
475 try { index = stoi(inputLine); } catch(const std::exception&) { GotoError("", 0); }
476 if(index < 0 || index >= (int)outNums) GotoError("", 0);
477
478 contentsInfo = m_contentsInfoList[index];
479
480 // select file
481 if (contentsInfo.filesNum > 1) {
482 for(CrInt32u i = 0; i < contentsInfo.filesNum; i++) {
483 printf("[%d] FileId:%d, FileName:%s\n", i,
484 contentsInfo.files[i].fileId,
485 contentsInfo.files[i].filePath);
486 }
487 std::cout << "index(0~ ):"; std::getline(std::cin, inputLine);
488 try { index = stoi(inputLine); } catch(const std::exception&) { GotoError("", 0); }
489 if(index < 0 || index >= (int)contentsInfo.filesNum) GotoError("", 0);
490 } else {
491 index = 0;
492 }
493 contentsFile = contentsInfo.files[index];
494
495 _showContentsInfo(contentsInfo);
496 _showContentsFile(contentsFile);
497
498 contentId = contentsInfo.contentId;
499 fileId = contentsFile.fileId;
500
501 result = 0;
502Error:
503 if (m_contentsInfoList) SCRSDK::ReleaseRemoteTransferContentsInfoList(device_handle, m_contentsInfoList);
504 if (m_captureDateList) SCRSDK::ReleaseRemoteTransferCapturedDateList(device_handle, m_captureDateList);
505 return result;
506}
507
508SCRSDK::CrError _controlMoviePlayback(int64_t device_handle, SCRSDK::CrMoviePlaybackControlType operation)
509{
510 SCRSDK::CrError err = SCRSDK::CrError_None;
511/*
512 CrMoviePlaybackControlType_Start = 0x00000001,
513 CrMoviePlaybackControlType_Stop,
514 CrMoviePlaybackControlType_Play = 0x00000004,
515 CrMoviePlaybackControlType_Pause,
516 CrMoviePlaybackControlType_Seek,
517*/
518 std::promise<void> eventPromise;
519 std::future<void> eventFuture = eventPromise.get_future();
520 std::future_status status;
521
522 setEventPromise(&eventPromise);
523 err = SCRSDK::ControlMoviePlayback(device_handle, operation, 0);
524 if(err) GotoError("", err);
525
526 status = eventFuture.wait_for(std::chrono::milliseconds(10000));
527 if(status != std::future_status::ready) GotoError("timeout",0);
528 try{
529 eventFuture.get();
530 } catch(const std::exception&) GotoError("", 0);
531 return 0;
532Error:
533 setEventPromise(nullptr);
534 return SCRSDK::CrError_Generic_Unknown;
535}
536
537SCRSDK::CrError _playbackStart(int64_t device_handle, SCRSDK::CrSlotNumber slotNumber, CrInt32u contentId, CrInt32u fileId, std::string ipAddress, CrString path)
538{
539 SCRSDK::CrError err = SCRSDK::CrError_None;
540 SCRSDK::CrMoviePlaybackSetting setting;
541
542 if(contentId == 0) {
543 std::cout << "select content\n";
544 return SCRSDK::CrError_Generic_Unknown;
545 }
546 if(ipAddress == "") {
547 std::cout << "enter ip address of this pc\n";
548 return SCRSDK::CrError_Generic_Unknown;
549 }
550
551 setting.slotId = slotNumber;
552 setting.contentsId = contentId;
553 setting.fileId = fileId;
554 setting.SetIpAddress(ipAddress.c_str());
555
556 err = SCRSDK::SetMoviePlaybackSetting(device_handle, &setting, 1);
557 if(err) GotoError("", err);
558
559 err = _controlMoviePlayback(device_handle, SCRSDK::CrMoviePlaybackControlType_Start);
560 if(err) goto Error;
561
562 m_fileVideo = new std::ofstream(path + CrString(DELIMITER CRSTR("temp.hevc")), std::ios::out | std::ios::binary);
563 if (m_fileVideo->bad()) GotoError("", 0);
564
565 m_fileAudio = new std::ofstream(path + CrString(DELIMITER CRSTR("temp.aac")), std::ios::out | std::ios::binary);
566 if (m_fileAudio->bad()) GotoError("", 0);
567 CrCout << "write files to:" << path.data() << "\n" "Please convert files with \"ffmpeg -i temp.hevc -i temp.aac -c copy output.mp4\"\n";
568
569 err = _controlMoviePlayback(device_handle, SCRSDK::CrMoviePlaybackControlType_Play);
570 if(err) goto Error;
571 return 0;
572Error:
573 if(m_fileVideo) {
574 m_fileVideo->close();
575 m_fileVideo = nullptr;
576 }
577 if(m_fileAudio) {
578 m_fileAudio->close();
579 m_fileAudio = nullptr;
580 }
581 return SCRSDK::CrError_Generic_Unknown;
582}
583
584std::vector<std::string> _split(std::string inputLine, char delimiter)
585{
586 std::vector<std::string> strArray;
587 if (inputLine.empty()) return strArray;
588
589 std::string tmp;
590 std::stringstream ss{inputLine};
591 while (getline(ss, tmp, delimiter)) {
592 strArray.push_back(tmp);
593 }
594 return strArray;
595}
596
597int64_t _stoll(std::string inputLine)
598{
599 int64_t data = 0;
600 if(inputLine.empty()) throw std::runtime_error("error");
601 try {
602 if (inputLine.compare(0, 2, "0x") == 0 || inputLine.compare(0, 2, "0X") == 0) {
603 data = std::stoull(inputLine.substr(2), nullptr, 16);
604 } else {
605 data = std::stoll(inputLine, nullptr, 10);
606 }
607 } catch(const std::exception& ex) {
608 throw ex;
609 }
610 return data;
611}
612
613int main(void)
614{
615 int result = -1;
616 SCRSDK::CrError err = SCRSDK::CrError_None;
617 SCRSDK::ICrEnumCameraObjectInfo* enumCameraObjectInfo = nullptr;
618 SCRSDK::ICrCameraObjectInfo* objInfo = nullptr;
619 DeviceCallback deviceCallback;
620 std::string inputLine;
621
622 #if defined(__APPLE__)
623 #define MAC_MAX_PATH 255
624 char pathBuf[MAC_MAX_PATH] = {0};
625 if(NULL == getcwd(pathBuf, sizeof(pathBuf) - 1)) return 1;
626 CrString path = pathBuf;
627 #else
628 CrString path = fs::current_path().native();
629 #endif
630
631 bool boolRet = SCRSDK::Init();
632 if(!boolRet) GotoError("", 0);
633
634 // enumeration
635 {
636 uint32_t count = 0;
637 uint32_t index = 1;
638
639 err = SCRSDK::EnumCameraObjects(&enumCameraObjectInfo, 3/*timeInSec*/);
640 if(err || !enumCameraObjectInfo) GotoError("no camera", err);
641
642 count = enumCameraObjectInfo->GetCount();
643 if(count >= 2) {
644 for (uint32_t i = 0; i < count; ++i) {
645 auto* info = enumCameraObjectInfo->GetCameraObjectInfo(i);
646 CrCout << '[' << i + 1 << "] " << _getModelId(info) << "\n";
647 }
648
649 std::cout << "select camera:"; std::getline(std::cin, inputLine);
650 try { index = stoi(inputLine); } catch(const std::exception&) { GotoError("", 0); }
651 if(index < 1 || index > count) GotoError("", 0);
652 }
653 objInfo = (SCRSDK::ICrCameraObjectInfo*)enumCameraObjectInfo->GetCameraObjectInfo(index - 1);
654 m_modelId = _getModelId(objInfo);
655 }
656
657 // connect
658 {
659 std::string fingerprint = "";
660 std::string userId = "";
661 std::string userPassword = "";
662 std::promise<void> eventPromise;
663 std::future<void> eventFuture = eventPromise.get_future();
664
665 if (objInfo->GetSSHsupport() == SCRSDK::CrSSHsupport_ON) {
666 err = _getIdPassword(objInfo, fingerprint, userId, userPassword); if(err) goto Error;
667 }
668
669 setEventPromise(&eventPromise);
670 err = SCRSDK::Connect(objInfo, &deviceCallback, &m_device_handle,
671 SCRSDK::CrSdkControlMode_RemoteTransfer,
672 SCRSDK::CrReconnecting_ON,
673 userId.c_str(), userPassword.c_str(), fingerprint.c_str(), (uint32_t)fingerprint.size());
674 if(err) GotoError("", err);
675
676 // std::future_status status = eventFuture.wait_for(std::chrono::milliseconds(3000));
677 // if(status != std::future_status::ready) GotoError("timeout",0);
678 try{
679 eventFuture.get();
680 } catch(const std::exception&) GotoError("", 0);
681 }
682
683 // set work directory
684 {
685 CrCout << "path=" << path.data() << "\n";
686 err = SCRSDK::SetSaveInfo(m_device_handle, const_cast<CrChar*>(path.data()), const_cast<CrChar*>(CRSTR("DSC")), -1/*startNo*/);
687 if(err) GotoError("", err);
688 }
689
690 std::this_thread::sleep_for(std::chrono::milliseconds(1000));
691
692 #define _printUsage() { \
693 std::cout << "usage:\n"; \
694 std::cout << " s [1~2(slot)] - Select content\n"; \
695 std::cout << " g [0(content),1(thumbnail),2(screennail)] - Get content\n"; \
696 std::cout << " d - Delete content\n"; \
697 std::cout << " ip <192.168.1.2(ip of this PC)> - set ip of this PC\n"; \
698 std::cout << " p [1(start),2(stop),4(resume),5(pause),6(seek)] - Playback content\n"; \
699 std::cout << "\n"; \
700 std::cout << " shot - Shutter Release\n"; \
701 std::cout << " postview <1(enable),0(disable)> <0(legacy),0x8000(file),0x8001(ram)>\n"; \
702 std::cout << " pull\n"; \
703 std::cout << "To exit, please enter 'q'.\n"; \
704 }
705 _printUsage();
706
707 {
708 SCRSDK::CrSlotNumber slotNumber = SCRSDK::CrSlotNumber_Slot1;
709 CrInt32u contentId = 0;
710 CrInt32u fileId = 0;
711 std::string ipAddress;
712
713 while(1) {
714 std::string inputLine;
715 std::cout << "cmd:"; std::getline(std::cin, inputLine);
716 std::vector<std::string> args = _split(inputLine, ' ');
717 int args2 = 0;
718 if(args.size() >= 2 && args[0] != "ip") {
719 try { args2 = stol(args[1]); } catch(const std::exception&) { GotoError("", 0); }
720 }
721
722 if(args.size() == 0) {
723
724 } else if(args[0] == "s") { // select content
725 if(args2 != 0) slotNumber = (SCRSDK::CrSlotNumber)args2;
726 err = _selectContent(m_device_handle, slotNumber, contentId, fileId);
727 //if(err) goto Error;
728
729 } else if(args[0] == "d" || args[0] == "g") { // delete/get content
730 std::promise<void> eventPromise;
731 std::future<void> eventFuture = eventPromise.get_future();
732
733 if(contentId == 0) {
734 std::cout << "select media\n";
735 continue;
736 }
737
738 #if defined(__linux__)
739 #define DivisionSize 0x1000000 // 16MB (16 * 1024 * 1024)
740 #else
741 #define DivisionSize 0x5000000 // 80MB (80 * 1024 * 1024)
742 #endif
743 setEventPromise(&eventPromise);
744 if(args[0] == "d") {
745 err = SCRSDK::DeleteRemoteTransferContentsFile(
746 m_device_handle, slotNumber, contentId);
747 contentId = 0;
748 } else if(args2 == 0) {
749 err = SCRSDK::GetRemoteTransferContentsDataFile(
750 m_device_handle, slotNumber, contentId, fileId,
751 DivisionSize, nullptr, nullptr);
752 } else if(args2 == 1) {
753 err = SCRSDK::GetRemoteTransferContentsCompressedDataFile(
754 m_device_handle, slotNumber, contentId, fileId,
755 SCRSDK::CrGetContentsCompressedDataType_Thumbnail, nullptr, nullptr);
756 } else if(args2 == 2) {
757 err = SCRSDK::GetRemoteTransferContentsCompressedDataFile(
758 m_device_handle, slotNumber, contentId, fileId,
759 SCRSDK::CrGetContentsCompressedDataType_Screennail, nullptr, nullptr);
760 } else {
761 GotoError("", 0);
762 }
763 if(err) GotoError("", err);
764
765 try{
766 eventFuture.get();
767 } catch(const std::exception&) GotoError("", 0);
768 std::cout << "OK\n";
769
770 } else if(args[0] == "ip") {
771 if(args.size() >= 2) {
772 ipAddress = args[1];
773 }
774 } else if(args[0] == "p") { // playback content
775 if(args2 == 0 || args2 == 1) { /*start*/
776 err = _playbackStart(m_device_handle, slotNumber, contentId, fileId, ipAddress, path);
777 } else {
778 err = _controlMoviePlayback(m_device_handle, (SCRSDK::CrMoviePlaybackControlType)args2);
779 }
780 //if(err) goto Error;
781
782 } else if (args[0] == "shot" || args[0] == "SHOT") { // Shutter Release
783 err = _shooting(m_device_handle);
784 //if (err) goto Error;
785
786 // ffmpeg -i temp.hevc -i temp.aac -c copy output.mp4
787 } else if(args[0] == "postview" && args.size() >= 3) {
788 int data = 0;
789 try { data = (int)_stoll(args[1]); } catch(const std::exception&) { GotoError("", 0); }
790 err = SCRSDK::SetDeviceSetting(m_device_handle, SCRSDK::Setting_Key_EnablePostView, data);
791 if(err) GotoError("", err)
792
793 try { data = (int)_stoll(args[2]); } catch(const std::exception&) { GotoError("", 0); }
794 err = SCRSDK::SetDeviceSetting(m_device_handle, SCRSDK::Setting_Key_PostViewTransferringType, data);
795 if(err) GotoError("", err)
796 } else if(args[0] == "pull") {
797 if(m_postview_size) {
798 uint32_t size = m_postview_size;
799 CrString filename = path + DELIMITER + m_postview_filename;
800
801 uint8_t* buf = (uint8_t*)malloc(size);
802 if(!buf) GotoError("", 0);
803
804 m_postview_size = 0;
805 m_postview_filename = CRSTR("");
806
807 err = SCRSDK::PullPostViewImage(m_device_handle, buf, size);
808 if(err) GotoError("", err)
809
810 std::ofstream file(filename, std::ios::out | std::ios::binary);
811 if (file.bad()) GotoError("", 0);
812 file.write((char*)buf, size);
813 file.close();
814 CrCout << filename.data() << "," << size << "\n";
815
816 free(buf);
817 }
818 } else if(args[0] == "q" || args[0] == "Q") {
819 break;
820 } else {
821 _printUsage();
822 }
823 }
824 }
825 result = 0;
826Error:
827 if(enumCameraObjectInfo) enumCameraObjectInfo->Release();
828
829 if(m_connected) {
830 std::promise<void> eventPromise;
831 std::future<void> eventFuture = eventPromise.get_future();
832 setEventPromise(&eventPromise);
833 SCRSDK::Disconnect(m_device_handle);
834 eventFuture.wait_for(std::chrono::milliseconds(3000));
835 }
836 if(m_device_handle) SCRSDK::ReleaseDevice(m_device_handle);
837 SCRSDK::Release();
838
839 if(m_fileVideo) {
840 m_fileVideo->close();
841 m_fileVideo = nullptr;
842 }
843 if(m_fileAudio) {
844 m_fileAudio->close();
845 m_fileAudio = nullptr;
846 }
847
848 return result;
849}