| | |
| | | //#include "HcRecord.h" |
| | | #include <time.h> |
| | | #include <dirent.h> |
| | | |
| | | #include "basic/pipe_element/ffmpeg/basic_struct_for_video_image.h" |
| | | using namespace std; |
| | | |
| | | devHttpServer_c::devHttpServer_c() |
| | |
| | | void devHttpServer_c::init(void) { |
| | | |
| | | std::string strDevId = appConfig.getStringProperty("DEV_ID"); |
| | | |
| | | // DSVAD010120181119 |
| | | m_batch = strDevId.substr(5, 2); |
| | | m_SerialNumber = strDevId.substr(7, 2); |
| | | |
| | | DBG("DevID: "<<strDevId<<" Batch: "<<m_batch <<" SerNum: "<<m_SerialNumber); |
| | | |
| | | fdfsClient.rwLock.wrlock(); |
| | | fdfsClient.fastFds = new FastFds("WebFDSClient.conf"); |
| | |
| | | img_str.append(fdfsClient.fastFds->getIp() + "/").append(img_tmp); |
| | | img_url.swap(img_str); |
| | | } |
| | | } else { |
| | | std::string img_str = "http://"; |
| | | if (fdfsClient.fastFds != nullptr) { |
| | | img_str.append(fdfsClient.fastFds->getIp() + "/").append(img_url); |
| | | img_url.swap(img_str); |
| | | } |
| | | } |
| | | |
| | | auto t_results = m_curlDownloadImg.download_jpeg(const_cast<char *>(img_url.c_str())); |
| | |
| | | } |
| | | } |
| | | |
| | | std::string devHttpServer_c::getAlarmImageFromVideoFile(std::string ip, unsigned int port, std::string content, |
| | | PResponse &response) { |
| | | DBG("ip:" << ip << "; port:" << port); |
| | | DBG("content: " << content); |
| | | Json::Reader reader; |
| | | Json::Value value; |
| | | try { |
| | | if (reader.parse(content, value)) { |
| | | std::string videoPath; |
| | | std::string devId = value["videoNum"].asString(); |
| | | std::string picDate = value["picDate"].asString(); |
| | | |
| | | //std::string path_uuid = videoPath;//value["path_uuid"].asString(); |
| | | std::string devHttpServer_c::getAlarmImageByPicDateAndDevId(const std::string& picDate,const std::string& devId, |
| | | PResponse &response) { |
| | | try { |
| | | if(!devId.empty() && !picDate.empty()) |
| | | { |
| | | std::string videoPath; |
| | | qint64 sub; |
| | | std::string path = getVideoPathByTime(picDate, devId, sub); |
| | | std::string path = getVideoPathByPicDate(picDate, devId, sub); |
| | | |
| | | if (path.empty()) { |
| | | ERR("{\"error\":\"not find path\"}"); |
| | |
| | | } |
| | | fdfsClient.rwLock.unlock(); |
| | | std::string result("{\"img_url\":\"" + img_url + "\"}"); |
| | | // cout << result << endl; |
| | | return result; |
| | | } else { |
| | | response->write(SimpleWeb::StatusCode::server_error_not_implemented, "{\"error\":\"传输错误,请检查!\"}"); |
| | | return ""; |
| | | // return "{\"error\":\"传输错误,请检查!\"}"; |
| | | } |
| | | } |
| | | catch (std::exception ex) { |
| | |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | std::string devHttpServer_c::getAlarmImageFromVideoFile(std::string ip, unsigned int port, std::string content, |
| | | PResponse &response) { |
| | | INFO("ip:" << ip << "; port:" << port << "content: " << content); |
| | | Json::Reader reader; |
| | | Json::Value value; |
| | | try { |
| | | if (reader.parse(content, value)) { |
| | | std::string devId = value["videoNum"].asString(); |
| | | std::string picDate = value["picDate"].asString(); |
| | | std::string imgKey = value["imgKey"].asString(); |
| | | //兼容旧版本 |
| | | if(imgKey=="undefined" || imgKey.empty()) |
| | | { |
| | | return getAlarmImageByPicDateAndDevId(picDate,devId,response); |
| | | } |
| | | else |
| | | { |
| | | return getAlarmImageByImageKeyAndDevId(imgKey,devId,response); |
| | | } |
| | | } |
| | | else{ |
| | | response->write(SimpleWeb::StatusCode::server_error_not_implemented, "{\"error\":\"传输错误,请检查!\"}"); |
| | | ERR("ImageURL:传输错误,请检查"); |
| | | return ""; |
| | | } |
| | | } |
| | | catch (std::exception ex) { |
| | | std::string message = "{\"error\":\"异常错误!"; |
| | | message.append(const_cast<char *>(ex.what())).append("\"}"); |
| | | response->write(SimpleWeb::StatusCode::server_error_not_implemented, message); |
| | | ERR("ImageURL:异常错误 "<<ex.what()); |
| | | return ""; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | std::string devHttpServer_c::getAlarmImageByImageKeyAndDevId(const std::string& imgKey,const std::string& devId, |
| | | PResponse &response) { |
| | | try { |
| | | if (!devId.empty() && !imgKey.empty()) { |
| | | std::string videoPath; |
| | | std::string path = getVideoPathByImgKey(imgKey, devId); |
| | | if (path.empty()) { |
| | | ERR("Not Find Path: "<<path); |
| | | return "{\"error\":\"未查到视频路径\"}"; |
| | | } |
| | | videoPath.clear(); |
| | | videoPath = path; |
| | | |
| | | VideoName_s_t videoSt = VideoName_s_t::fromString(path); |
| | | ImageName_s_t imgSt = ImageName_s_t::fromString(imgKey); |
| | | |
| | | //#todo 按照时间命名 |
| | | std::string str_imgName(AppUtil::getTimeString() + ".jpg");// = "test.jpg"; |
| | | |
| | | auto frameIdDiff = imgSt.m_frameId-videoSt.m_startFrameId; |
| | | char selectExpBuff[32]={0}; |
| | | std::string strSelectTemplate=R"#( -vf "select=eq(n\,%d)")#"; |
| | | sprintf(selectExpBuff,strSelectTemplate.c_str(),frameIdDiff-1); |
| | | if(videoSt.Valid() && imgSt.Valid() ) { |
| | | std::string cmd("ffmpeg -i '" + videoPath+"'"+std::string(selectExpBuff)+" -vframes 1" +" -y '" + str_imgName + "'"); |
| | | INFO("Video To Image Cmd: "<<cmd); |
| | | system(cmd.c_str()); |
| | | } |
| | | else { |
| | | ERR("Parse Video and Image Failed Path: "<<path <<" ImageId: "<<imgKey); |
| | | return "{\"error\":\"未查到视频路径\"}"; |
| | | } |
| | | |
| | | cv::Mat img = cv::imread(str_imgName); |
| | | if (img.empty()) { |
| | | ERR("{\"error\":\"Video File error\"}"); |
| | | return "{\"error\":\"视频文件错误\"}"; |
| | | } |
| | | |
| | | std::vector<unsigned char> buffer; |
| | | CvUtil::cvMat2Buffer(img, buffer); |
| | | std::string img_url = "http://"; |
| | | fdfsClient.rwLock.rdlock(); |
| | | if (fdfsClient.fastFds != nullptr) { |
| | | std::string t_strImg = ""; |
| | | if (!fdfsClient.fastFds->uploadFile(buffer, t_strImg, "jpg")) { |
| | | img_url = "upload image fail"; |
| | | ERR("Upload Image Failed "<<str_imgName); |
| | | } else { |
| | | std::string str_tmp_cmd("rm -f '" + str_imgName + "'"); |
| | | system(str_tmp_cmd.c_str()); |
| | | img_url.append(t_strImg); |
| | | img_url.clear(); |
| | | img_url = t_strImg; |
| | | } |
| | | } |
| | | fdfsClient.rwLock.unlock(); |
| | | std::string result("{\"img_url\":\"" + img_url + "\"}"); |
| | | INFO("ImageURL:"<<img_url); |
| | | return result; |
| | | } else { |
| | | response->write(SimpleWeb::StatusCode::server_error_not_implemented, "{\"error\":\"传输错误,请检查!\"}"); |
| | | ERR("ImageURL:传输错误,请检查"); |
| | | return ""; |
| | | } |
| | | } |
| | | catch (std::exception ex) { |
| | | std::string message = "{\"error\":\"异常错误!"; |
| | | message.append(const_cast<char *>(ex.what())).append("\"}"); |
| | | response->write(SimpleWeb::StatusCode::server_error_not_implemented, message); |
| | | ERR("ImageURL:异常错误 "<<ex.what()); |
| | | return ""; |
| | | } |
| | | } |
| | | |
| | | |
| | | std::string |
| | | devHttpServer_c::getRecordVideoPath(std::string ip, unsigned int port, std::string content, PResponse &response) { |
| | | |
| | | Json::Reader reader; |
| | | Json::Value value; |
| | | |
| | | INFO("REQ From: "<<ip<<":"<<port<<" Content:"<<content); |
| | | if (reader.parse(content, value)) { |
| | | std::string devId = value["videoNum"].asString(); |
| | | std::string picDate = value["picDate"].asString(); |
| | | qint64 sub; |
| | | std::string path = getVideoPathByTime(picDate, devId, sub); |
| | | if (path.empty()) { |
| | | std::string imgKey = value["imgKey"].asString(); |
| | | std::string path; |
| | | |
| | | return "{\"ret_status\":\"内容有误,请检查!\"}"; |
| | | //兼容旧版本 |
| | | if(imgKey=="undefined"||imgKey.empty()) |
| | | { |
| | | qint64 sub; |
| | | path = getVideoPathByPicDate(picDate,devId,sub); |
| | | } |
| | | else |
| | | { |
| | | path = getVideoPathByImgKey(imgKey,devId); |
| | | } |
| | | //std::string path = getVideoPathByImgKey(imgKey, devId, sub); |
| | | ERR("VideoNum: "<<devId <<" PicDate: "<<picDate<<" imgKey: "<<imgKey); |
| | | if (path.empty()) { |
| | | std::string strRsp = "{\"ret_status\":\"内容有误,请检查!\"}"; |
| | | ERR("RSP:"<< strRsp); |
| | | return strRsp; |
| | | } else { |
| | | std::string result = "{\"file_path\":\"" + path + "\"}"; |
| | | INFO("RSP:"<<result); |
| | | return result; |
| | | } |
| | | } else { |
| | | return "{\"ret_status\":\"传输错误,请检查!\"}"; |
| | | std::string strRsp="{\"ret_status\":\"传输错误,请检查!\"}"; |
| | | ERR("RSP:"<< strRsp); |
| | | return strRsp; |
| | | } |
| | | } |
| | | |
| | | |
| | | std::string devHttpServer_c::findDevId(std::string ip, unsigned int port, std::string content, PResponse &response) { |
| | | |
| | |
| | | return true; |
| | | } |
| | | |
| | | std::string devHttpServer_c::getVideoPathByTime(const std::string &time, const std::string &camId, qint64 &sub) { |
| | | |
| | | std::string devHttpServer_c::getVideoPathByPicDate(const std::string &time, const std::string &camId, qint64 &sub) { |
| | | std::string t_FilePath = appConfig.getStringProperty("cutPath"); |
| | | |
| | | bool find = false; |
| | |
| | | |
| | | } |
| | | |
| | | |
| | | std::string devHttpServer_c::GetVideoNameByImgKey(const std::string& imgKey,const std::string& strPath) { |
| | | static std::mutex g_mutex; |
| | | std::lock_guard<std::mutex> lock(g_mutex); |
| | | std::vector<std::string> vec = forEachFileByImgKey(strPath); |
| | | ImageName_s_t imgSt = ImageName_s_t::fromString(imgKey); |
| | | if(!imgSt.Valid()) |
| | | { |
| | | ERR("ParseImageName Failed : "<<imgKey); |
| | | return ""; |
| | | } |
| | | std::vector<VideoName_s_t> videoStVec; |
| | | for (const auto &item : vec) { |
| | | auto videoParseResult = VideoName_s_t::fromString(item); |
| | | if (videoParseResult.Valid()) { |
| | | if (videoParseResult.m_startFrameId <= imgSt.m_frameId && |
| | | imgSt.m_frameId <= videoParseResult.m_endFrameId) { |
| | | auto imgTm = AppUtil::ParseFromHypenTimeStr(imgSt.m_timeStamp); |
| | | auto videoTm = AppUtil::ParseFromHypenTimeStr(videoParseResult.m_timeStamp); |
| | | if (AppUtil::IsRightAfterLeft(imgTm, videoTm)) { |
| | | videoStVec.emplace_back(videoParseResult); |
| | | INFO("Image " << imgKey << " Video: " << item << " Match"); |
| | | } else { |
| | | ERR("Image " << imgKey << " Video: " << item << " Not Match"); |
| | | } |
| | | } else{ |
| | | ERR("ImageID: "<<imgSt.m_frameId <<" VideoRange: "<<videoParseResult.m_startFrameId<<" , "<<videoParseResult.m_endFrameId); |
| | | } |
| | | |
| | | } else { |
| | | ERR("VideoName : " << item << " Parse Failed"); |
| | | } |
| | | } |
| | | |
| | | if (videoStVec.size() >= 1) { |
| | | std::string strVideoName = strPath + videoStVec[0].ToVideoName(); |
| | | INFO("ImageName: "<<imgKey<<" SingleMatchVideo: "<<strVideoName); |
| | | return strVideoName; |
| | | } else { |
| | | ERR("ImageName: "<<imgKey<<" MatchVideoCount: "<<videoStVec.size()); |
| | | for(auto& item:vec) |
| | | { |
| | | ERR("VideoName: "<<item); |
| | | } |
| | | return ""; |
| | | } |
| | | } |
| | | |
| | | //新的根据图片名称获取路径的方法 |
| | | std::string devHttpServer_c::getVideoPathByImgKey(const std::string &imgKey, const std::string &camId) |
| | | { |
| | | INFO("GetVideoFor: "<<imgKey<<" CamID:"<<camId); |
| | | ImageName_s_t imgSt= ImageName_s_t::fromString(imgKey); |
| | | |
| | | struct tm imgTime = AppUtil::ParseFromHypenTimeStr(imgSt.m_timeStamp); |
| | | char curFolder[128]={0}; |
| | | // 201901/26/2019012614 ---- 201901/26/2019012615 {年月}/{日}/{年月日时}/ |
| | | sprintf(curFolder,"%04d%02d/%02d/%04d%02d%02d%02d/",imgTime.tm_year+1900,imgTime.tm_mon+1, |
| | | imgTime.tm_mday, |
| | | imgTime.tm_year+1900,imgTime.tm_mon+1,imgTime.tm_mday,imgTime.tm_hour); |
| | | std::string t_FilePath = appConfig.getStringProperty("cutPath"); |
| | | std::string videoPath = t_FilePath+"/"+camId+"/"+std::string(curFolder); |
| | | return GetVideoNameByImgKey(imgKey,videoPath); |
| | | } |
| | | |
| | | |
| | | |
| | | qint64 devHttpServer_c::getVideoTime(/*const std::string &videoPath,*/std::string &str_tmpTime) { |
| | | // std::string cmd_getVideoFileTime( |
| | | // " ffmpeg -i '" + videoPath + "' 2>&1 | grep 'Duration' | cut -d ' ' -f 4 | sed s/,//"); |
| | |
| | | return len_ms; |
| | | } |
| | | |
| | | //获取某个目录下的所有文件,不带扩展名 |
| | | std::vector<std::string> devHttpServer_c::forEachFile(const std::string &dir_name) { |
| | | std::vector<std::string> v; |
| | | auto dir = opendir(dir_name.data()); |
| | |
| | | return v; |
| | | } |
| | | |
| | | //获取某个目录下的所有文件,带扩展名 |
| | | std::vector<std::string> devHttpServer_c::forEachFileByImgKey(const std::string &dir_name) { |
| | | std::vector<std::string> v; |
| | | auto dir = opendir(dir_name.data()); |
| | | struct dirent *ent; |
| | | int len = 0; |
| | | if (dir) { |
| | | while ((ent = readdir(dir)) != NULL) { |
| | | std::string filename = std::string(ent->d_name); |
| | | std::string temp; |
| | | if (filename != "." && filename != "..") { |
| | | v.push_back(filename); |
| | | } |
| | | |
| | | } |
| | | closedir(dir); |
| | | } |
| | | return v; |
| | | } |
| | | |
| | | std::string devHttpServer_c::addPersons(std::string ip, unsigned int port, std::string content, PResponse &response) { |
| | | DBG("ip:" << ip << "; port:" << port); |
| | | // DBG("content: " << content); |