has('mine')) { // $this->pre_url = config('haikang.' . $request->input('mine') . '.pre_url'); // https://120.253.79.51:4433 // $this->app_key = config('haikang.' . $request->input('mine') . '.app_key'); // 25720460 // $this->app_secret = config('haikang.' . $request->input('mine') . '.app_secret'); // qqP7NLcIDwO9MgtYmp8L // $this->artemis = config('haikang.' . $request->input('mine') . '.artemis'); // /artemis // } else { // $this->pre_url = env('HAI_KANG_URL'); // https://120.253.79.51:4433 // $this->app_key = env('HAI_KANG_APP_KEY'); // 25720460 // $this->app_secret = env('HAI_KANG_APP_SECRET'); // qqP7NLcIDwO9MgtYmp8L // $this->artemis = env('HAI_KANG_ARTEMIS_PATH'); // /artemis // } // $this->pre_url = 'https://10.71.252.64:4433'; // https://120.253.79.51:4433 // $this->app_key = '25720460'; // 25720460 // $this->app_secret = 'qqP7NLcIDwO9MgtYmp8L'; // qqP7NLcIDwO9MgtYmp8L // $this->artemis = '/artemis'; // /artemis $this->pre_url = Input::get('url'); // https://120.253.79.51:4433 $this->app_key = Input::get('key'); // 25720460 $this->app_secret = Input::get('secret'); // qqP7NLcIDwO9MgtYmp8L $this->artemis = '/artemis'; // /artemis list($msec, $sec) = explode(' ', microtime()); $this->time = (float)sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000); } /** * 获取区域列表 * @return bool|mixed|string */ public function getRegionsList() { $url = $this->artemis . '/api/resource/v1/regions'; //请求参数 $params = []; // $params['pageNo'] = $request->has('pageNo') ? intval($request->input('pageNo')) : 1; // $params['pageSize'] = $request->has('pageSize') ? intval($request->input('pageSize')) : 1000; $params['pageNo'] = 1; $params['pageSize'] = 1000; $this->sign = $this->get_sign($url); $type = Input::get('type'); $mine_id = Input::get('mine_id'); $result = $this->curlPost($this->pre_url . $url, json_encode($params)); $result = json_decode($result, true); $area_list = []; if (isset($result['code']) && $result['code'] == 0) { $list = $result['data']['list']; foreach ($list as $key => $item) { $area_list[] = $item['indexCode']; if ($item['parentIndexCode'] == '-1') { unset($list[$key]); } } $result['data']['list'] = array_values($list); } if ($type == CameraEnum::REQUEST_TYPE_API) { $result['data']['list'] = $this->regionsTree($result['data']['list']); } else { //先删除不存在的区域 if ($area_list) { MineList::where('degree', 'like', $mine_id . '|%')->whereNotIn('index_code', $area_list)->delete(); } //更新区域 $result['data']['list'] = $this->saveTree($result['data']['list'], $mine_id); } return $result; } protected function regionsTree($regions, $pid = 'root000000') { $arr = []; if (empty($regions)) { return []; } foreach ($regions as $key => $value) { if (isset($value['parentIndexCode']) && $value['parentIndexCode'] == $pid) { $arr[$key]['indexCode'] = $value['indexCode']; $arr[$key]['mine_id'] = $value['indexCode']; $arr[$key]['name'] = $value['name']; $arr[$key]['parentIndexCode'] = $value['parentIndexCode']; $arr[$key]['treeCode'] = $value['treeCode']; $arr[$key]['children'] = array_values(self::regionsTree($regions, $value['indexCode'])); unset($arr[$key]['indexCode']); unset($arr[$key]['parentIndexCode']); unset($arr[$key]['treeCode']); if (count($arr[$key]['children']) == 0) { unset($arr[$key]['children']); } } } return array_values($arr); } protected function saveTree($regions, $parent_id, $pid = 'root000000') { $arr = []; if (empty($regions)) { return []; } $mineService = new MineServices(); $mineService->initMineList(); $arr_count = count($regions); foreach ($regions as $key => $value) { if (isset($value['parentIndexCode']) && $value['parentIndexCode'] == $pid) { $arr[$key]['indexCode'] = $value['indexCode']; $arr[$key]['mine_id'] = $value['indexCode']; $arr[$key]['name'] = str_replace('#', '号', $value['name']); $arr[$key]['parentIndexCode'] = $value['parentIndexCode']; $arr[$key]['treeCode'] = $value['treeCode']; $id = MineList::where('index_code', $value['indexCode'])->value('id'); $params = [ 'id' => $id, 'parent_id' => $parent_id, 'title' => $value['name'], 'sort' => $arr_count - $key, 'index_code' => $value['indexCode'], ]; $result = $mineService->add($params); $mine_id = $result->id; $arr[$key]['children'] = array_values(self::saveTree($regions, $mine_id, $value['indexCode'])); if (count($arr[$key]['children']) == 0) { unset($arr[$key]['children']); } } } return array_values($arr); } /** * 获取区域监控列表 * @return bool|mixed|string */ public function getCamerasList() { if (!Input::has('indexCode')) { return $this->error(1, '缺少必要参数'); } $url = $this->artemis . '/api/resource/v1/regions/regionIndexCode/cameras'; //请求参数 $params = []; $params['regionIndexCode'] = Input::get('indexCode'); // $params['pageNo'] = $request->has('pageNo') ? intval($request->input('pageNo')) : 1; // $params['pageSize'] = $request->has('pageSize') ? intval($request->input('pageSize')) : 1000; $params['pageNo'] = 1; $params['pageSize'] = 1000; $this->sign = $this->get_sign($url); $result = $this->curlPost($this->pre_url . $url, json_encode($params)); $result = json_decode($result, true); return $result; } public function getCameraStatus($indexCode){ $url = $this->artemis . '/api/nms/v1/online/camera/get'; $params = []; $params['regionId'] = 'root000000'; $params['includeSubNode'] = '1'; $params['indexCodes'] = [$indexCode]; $params['status'] = '1'; $params['pageNo'] = 1; $params['pageSize'] = 20; $this->sign = $this->get_sign($url); $result_status = $this->curlPost($this->pre_url . $url, json_encode($params)); $result_status = json_decode($result_status, true); if(isset($result_status['data']['list'][0]['online']) && $result_status['data']['list'][0]['online'] == 0){ return 2;//离线 }else{ return 1;//在线 } } /** * 获取摄像头码流url * @return array|mixed */ public function getCamerasUrl() { if (!Input::has('cameraIndexCode')) { return $this->error(1, '缺少必要参数'); } $protocol = Input::get('protocol', 'hls'); $streamType = Input::get('streamType', 1); $url = $this->artemis . '/api/video/v1/cameras/previewURLs'; // $cameras_info = json_decode($this->getCamerasInfo(Input::all()), true); //请求参数 $params = []; // $params['regionIndexCode'] = $request->input('regionIndexCode'); $params['cameraIndexCode'] = Input::get('cameraIndexCode'); $params['streamType'] = $streamType; //0主码流 1子码流 2第三码流 $params['protocol'] = $protocol; $params['transmode'] = 1; //0:UDP 1:TCP $params['expand'] = 'transcode=1&systemformat=ps&videotype=h264'; $this->sign = $this->get_sign($url); $result = $this->curlPost($this->pre_url . $url, json_encode($params)); $result = json_decode($result, true); if (isset($result['code']) && $result['code'] == 0) { // 将内网地址替换为外网地址 $video_url = $result['data']['url']; preg_match('/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/i', $video_url, $res); // 提取内网ip preg_match('/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/i', $this->pre_url, $res_n); // 提取外网ip $result['data']['url'] = str_replace($res, $res_n, $video_url); } return $result; } /** * 获取摄像头详情 * @param array $data * @return array|bool|string */ public function getCamerasInfo($data) { $url = $this->artemis . '/api/resource/v1/cameras/indexCode'; //请求参数 $params = []; $params['cameraIndexCode'] = $data['cameraIndexCode']; $this->sign = $this->get_sign($url); $result = $this->curlPost($this->pre_url . $url, json_encode($params)); return $result; } //获取编码设备信息 public function getTranscodeInfo() { $url = $this->artemis . '/api/resource/v1/encodeDevice/get'; //请求参数 $params = []; $params['pageNo'] = 1; $params['pageSize'] = 1; $this->sign = $this->get_sign($url); $result = $this->curlPost($this->pre_url . $url, json_encode($params)); return $result; } //根据区域获取下级编码设备列表 public function getTest() { $url = $this->artemis . '/api/resource/v1/encodeDevice/subResources'; //请求参数 $params = []; $params['pageNo'] = 1; $params['pageSize'] = 1000; $params['regionIndexCode'] = Input::get('indexCode'); $this->sign = $this->get_sign($url); $result = $this->curlPost($this->pre_url . $url, json_encode($params)); $result = json_decode($result, true); return $result; } //获取编码设备列表 public function getTranscodeList() { $url = $this->artemis . '/api/resource/v1/encodeDevice/subResources'; //请求参数 $params['regionIndexCode'] = 'root000000'; $params['pageNo'] = 1; $params['pageSize'] = 100; $this->sign = $this->get_sign($url); $result = $this->curlPost($this->pre_url . $url, json_encode($params)); $result = json_decode($result, true); return $result; } public function getRegionsInfo() { $url = $this->artemis . '/api/resource/v1/region/regionCatalog/regionInfo'; //请求参数 $params = []; $indexCodes = Input::get('indexCodes'); $params['indexCodes'] = $indexCodes; $this->sign = $this->get_sign($url); $result = $this->curlPost($this->pre_url . $url, json_encode($params)); $result = json_decode($result, true); // if (isset($result['code']) && $result['code'] == 0) { // } return $result; } public function getPlaybackRtsp(){ $result['status'] = true; $result['msg'] = ApiEnum::RETURN_SUCCESS; $camera_id = Input::get('camera_id'); $start_time = Input::get('start_time'); $end_time = Input::get('end_time'); $query = CameraList::where('id', $camera_id)->first(); // $url = $this->artemis.'/api/video/v2/cameras/playbackURLs'; // $params['cameraIndexCode'] = $query->index_code; // $params['recordLocation'] = 0; // $params['protocol'] = 'rtsp';//rtsp // $params['transmode'] = 0; // $params['beginTime'] = $start_time; // $params['endTime'] = $end_time; // $params['uuid'] = ''; // $params['expand'] = 'transcode=0'; // $params['streamform'] = 'ps'; // $params['lockType'] = 0; $url = $this->artemis.'/api/video/v1/cameras/playbackURLs'; $params['cameraIndexCode'] = $query->index_code; $params['recordLocation'] = 0; $params['protocol'] = 'rtsp';//rtsp // $params['transmode'] = 0; $params['beginTime'] = $start_time; $params['endTime'] = $end_time; // $params['uuid'] = ''; // $params['expand'] = 'streamform=ps'; $params['streamType'] = 1; //0主码流 1子码流 2第三码流 $params['transmode'] = 1; //0:UDP 1:TCP $params['expand'] = 'transcode=1&systemformat=ps&videotype=h264'; $this->sign = $this->get_sign($url); $data = $this->curlPost($this->pre_url . $url, json_encode($params)); $data = json_decode($data, true); if (isset($data['code']) && $data['code'] == 0) { // 将内网地址替换为外网地址 $video_url = $data['data']['url']; preg_match('/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/i', $video_url, $res); // 提取内网ip preg_match('/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/i', $this->pre_url, $res_n); // 提取外网ip $data['data']['url'] = str_replace($res, $res_n, $video_url); } if ($data['data']['url']) { $result['camera_id'] = $camera_id; $result['url'] = $data['data']['url']; } else { $result['status'] = false; $result['msg'] = ApiEnum::HK_REQUEST_FAIL; } return $result; } public function getPlaybackByEasy(){ $result['status'] = true; $result['msg'] = ApiEnum::RETURN_SUCCESS; $camera_id = Input::get('camera_id'); $start_time = Input::get('start_time'); $end_time = Input::get('end_time'); $old_time = Input::get('time'); $query = CameraList::where('id', $camera_id)->first(); $degree = MineList::where('id', $query->mine_id)->value('degree'); $degree = explode('|', $degree); $mine_list = MineList::whereIn('id', $degree)->select(['title'])->get()->toArray(); $time = explode('T',$start_time); $time = substr($time[1],0,5); $time = str_replace(":","",$time); $path = ''; $path = '/'.$mine_list[0]['title']; $new_camera_name = str_replace('-','',$query->camera_name); $new_camera_name = str_replace('#','号',$new_camera_name); $path .= '/' . $new_camera_name.'回放'.$time; $playback = DB::table('playback') ->where('camera_id',$camera_id) ->where('start_time',$old_time['start_time']) ->where('end_time',$old_time['end_time']) ->where('deleted_at',null)->get(); //已有拉流id,直接返回拉流链接 if(count($playback)>0){ if($playback[0]->revert_back_id != 'NullId'){ $result['data'] = [ 'camera_id' => $camera_id, 'url' => env('EASY_DARWIN_JF_RTSP') . $path ]; return $result; } } $url = $this->artemis.'/api/video/v1/cameras/playbackURLs'; $params['cameraIndexCode'] = $query->index_code; $params['recordLocation'] = 0; $params['protocol'] = 'rtsp';//rtsp $params['beginTime'] = $start_time; $params['endTime'] = $end_time; $params['streamType'] = 1; //0主码流 1子码流 2第三码流 $params['transmode'] = 1; //0:UDP 1:TCP $params['expand'] = 'streamform=rtp'; $this->sign = $this->get_sign($url); $data = $this->curlPost($this->pre_url . $url, json_encode($params)); $data = json_decode($data, true); if(!$data['data']['url']){//切换码流 $params['streamType'] = 0; $this->sign = $this->get_sign($url); $data = $this->curlPost($this->pre_url . $url, json_encode($params)); $data = json_decode($data, true); } if(!$data['data']['url']){ $result['status'] = false; $result['msg'] = ApiEnum::HK_REQUEST_FAIL; return $result; } $data = [ 'url' => $data['data']['url'].'?beginTime='.$start_time.'&endTime='.$end_time.'&playBackMode=1', 'customPath' => $path, ]; //请求流媒体服务器拉流 $curl = env('EASY_DARWIN_JF_URL') . CameraEnum::API_STREAM_START . '?' . http_build_query($data); $curl_res = curl_request($curl); if(strpos($curl_res,' ')){ $result['status'] = false; $result['msg'] = ApiEnum::EASY_DAWIN_REQUEST_FAIL; return $result; } //更新拉流id // CameraList::where('id', $camera_id)->update( // [ // 'revert_back_id' => trim($curl_res, '"'), // ] // ); if(count($playback)>0){ $back_data['revert_back_id'] = trim($curl_res, '"'); DB::table('playback')->where('id',$playback[0]->id)->update($back_data); } $result['data'] = [ 'camera_id' => Input::get('camera_id'), 'url' => env('EASY_DARWIN_JF_RTSP') . $path ]; return $result; } public function getPlaybackRtmp(){ $camera_id = Input::get('camera_id'); $start_time = Input::get('start_time'); $end_time = Input::get('end_time'); $stream_type = Input::get('stream_type'); $query = CameraList::where('id', $camera_id)->first(); // $url = $this->artemis.'/api/video/v2/cameras/playbackURLs'; // $params['cameraIndexCode'] = $query->index_code; // $params['recordLocation'] = 0; // $params['protocol'] = 'rtsp';//rtsp // $params['transmode'] = 0; // $params['beginTime'] = $start_time; // $params['endTime'] = $end_time; // $params['uuid'] = ''; // $params['expand'] = 'transcode=0'; // $params['streamform'] = 'ps'; // $params['lockType'] = 0; $url = $this->artemis.'/api/video/v1/cameras/playbackURLs'; $params['cameraIndexCode'] = $query->index_code; $params['recordLocation'] = 0; $params['protocol'] = 'rtmp';//rtsp // $params['transmode'] = 0; $params['beginTime'] = $start_time; $params['endTime'] = $end_time; $params['streamType'] = $stream_type; //0主码流 1子码流 2第三码流 $params['transmode'] = 1; //0:UDP 1:TCP $params['expand'] = 'transcode=1&systemformat=ps&videotype=h264'; // $params['uuid'] = ''; // $params['expand'] = 'streamform=ps'; $this->sign = $this->get_sign($url); $data = $this->curlPost($this->pre_url . $url, json_encode($params)); $data = json_decode($data, true); if (isset($data['code']) && $data['code'] == 0) { // 将内网地址替换为外网地址 $video_url = $data['data']['url'].'?beginTime='.$start_time.'&endTime='.$end_time.'&playBackMode=1'; preg_match('/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/i', $video_url, $res); // 提取内网ip preg_match('/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/i', $this->pre_url, $res_n); // 提取外网ip $data['data']['url'] = str_replace($res, $res_n, $video_url); } return $data; } //海康获取rtsp public function getHikRtsp(){ $result['status'] = true; $result['msg'] = ApiEnum::RETURN_SUCCESS; $query = CameraList::where('id',Input::get('camera_id'))->first(); if (!$query) { $result['status'] = false; $result['msg'] = ApiEnum::NO_CAMERA_URL; return $result; } $degree = MineList::where('id', $query->mine_id)->value('degree'); $mine_list = MineList::whereIn('id', explode('|', $degree))->select(['title'])->get()->toArray(); $path = ''; foreach ($mine_list as $key => $val) { $path .= '/' . $val['title']; } $new_camera_name = str_replace('-','',$query->camera_name); $new_camera_name = str_replace('#','号',$new_camera_name); $path .= '/' . $new_camera_name; if($query->code_stream == 2){ $code_stream = 0; }else{ $code_stream = 1; } $url = $this->artemis.'/api/video/v1/cameras/previewURLs'; $params['cameraIndexCode'] = $query->index_code; $params['streamType'] = $code_stream; //0主码流 1子码流 2第三码流 $params['protocol'] = 'rtsp';//rtsp $params['transmode'] = 1; //0:UDP 1:TCP $params['expand'] = 'streamform=rtp'; $this->sign = $this->get_sign($url); $rtsp = $this->curlPost($this->pre_url . $url, json_encode($params)); $rtsp = json_decode($rtsp, true); if($rtsp['data']['url']){ //访问记录 $log['mine_id'] = $query->mine_id; $log['camera_id'] = Input::get('camera_id'); $log['log'] = '海康接口返回rtsp成功'; $log['status'] = 0;//正常 $log['created_at'] = date('Y-m-d H:i:s'); $log['updated_at'] = date('Y-m-d H:i:s'); DB::table('log')->insert($log); }else{ //访问记录 $log['mine_id'] = $query->mine_id; $log['camera_id'] = Input::get('camera_id'); $log['log'] = '海康接口返回rtsp失败'; $log['status'] = 1;//异常 $log['created_at'] = date('Y-m-d H:i:s'); $log['updated_at'] = date('Y-m-d H:i:s'); DB::table('log')->insert($log); } $ffmpeg_rtsp = $rtsp['data']['url']; $rtsp['data']['url'] = substr_replace($rtsp['data']['url'],env('NMJT_IP'),7,12); $result['data'] = [ 'camera_id' => Input::get('camera_id'), 'url' => $rtsp['data']['url'] ]; //查询是否存在封面图 $cover_picture = CameraList::where('id', Input::get('camera_id'))->value('cover_picture'); if (!$cover_picture) { register_shutdown_function(array($this, "getFirstPicture"),$path,$ffmpeg_rtsp); } return $result; } //海康获取rtmp public function getHikHls(){ $result['status'] = true; $result['msg'] = ApiEnum::RETURN_SUCCESS; $query = CameraList::where('id',Input::get('camera_id'))->first(); if (!$query) { $result['status'] = false; $result['msg'] = ApiEnum::NO_CAMERA_URL; return $result; } $degree = MineList::where('id', $query->mine_id)->value('degree'); $mine_list = MineList::whereIn('id', explode('|', $degree))->select(['title'])->get()->toArray(); $path = ''; foreach ($mine_list as $key => $val) { $path .= '/' . $val['title']; } $new_camera_name = str_replace('-','',$query->camera_name); $new_camera_name = str_replace('#','号',$new_camera_name); $path .= '/' . $new_camera_name; if($query->code_stream == 2){ $code_stream = 0; }else{ $code_stream = 1; } $url = $this->artemis.'/api/video/v1/cameras/previewURLs'; $params['cameraIndexCode'] = $query->index_code; $params['streamType'] = $code_stream; //0主码流 1子码流 2第三码流 $params['protocol'] = 'hls';//rtmp $params['transmode'] = 1; //0:UDP 1:TCP $params['expand'] = 'streamform=rtp'; $this->sign = $this->get_sign($url); $rtmp = $this->curlPost($this->pre_url . $url, json_encode($params)); $rtmp = json_decode($rtmp, true); if($rtmp['data']['url']){ //访问记录 $log['mine_id'] = $query->mine_id; $log['camera_id'] = Input::get('camera_id'); $log['log'] = '海康接口返回rtsp成功'; $log['status'] = 0;//正常 $log['created_at'] = date('Y-m-d H:i:s'); $log['updated_at'] = date('Y-m-d H:i:s'); DB::table('log')->insert($log); }else{ //访问记录 $log['mine_id'] = $query->mine_id; $log['camera_id'] = Input::get('camera_id'); $log['log'] = '海康接口返回rtsp失败'; $log['status'] = 1;//异常 $log['created_at'] = date('Y-m-d H:i:s'); $log['updated_at'] = date('Y-m-d H:i:s'); DB::table('log')->insert($log); } $ffmpeg_rtmp = $rtmp['data']['url']; $rtmp['data']['url'] = substr_replace($rtmp['data']['url'],env('HK_HLS'),7,17); $result['data'] = [ 'camera_id' => Input::get('camera_id'), 'url' => $rtmp['data']['url'] ]; //查询是否存在封面图 $cover_picture = CameraList::where('id', Input::get('camera_id'))->value('cover_picture'); if (!$cover_picture) { register_shutdown_function(array($this, "getFirstPicture"),$path,$ffmpeg_rtmp); } return $result; } //宁煤集团获取rtsp流后获取首帧图片 public function getFirstPicture($path,$ffmpeg_rtsp){ if (!is_dir('/www/wwwroot/video.nxjiewei.com/public/' . CameraEnum::M3U8_FILE_PATH . '/' . $path)) { mkdir('/www/wwwroot/video.nxjiewei.com/public/' . CameraEnum::M3U8_FILE_PATH . '/' . $path, 0777, true); } // dd($result_td['content'][0]['url']); $exec = 'nohup /usr/bin/ffmpeg -i "' . $ffmpeg_rtsp . '" -vcodec copy -acodec copy -vbsf h264_mp4toannexb -f hls -hls_flags delete_segments -segment_list_size 10 -hls_list_size 2 /www/wwwroot/video.nxjiewei.com/public/' . CameraEnum::M3U8_FILE_PATH . $path . '/' . CameraEnum::M3U8_FILE_NAME . ' >/dev/null &'; shell_exec($exec); //sleep10秒生成文件 $i = 1; while ($i <= 10) { //判断m3u8文件是否存在 $file_exists = file_exists(public_path() . '/' . CameraEnum::M3U8_FILE_PATH . $path . '/' . CameraEnum::M3U8_FILE_NAME); //判断ts文件是否存在 $ts_exists = glob(public_path() . '/' . CameraEnum::M3U8_FILE_PATH . $path . '/' . CameraEnum::TS_FILE_SUFFIX); if ($file_exists && $ts_exists) { //获取第一帧作为封面图 $file_name = time() . CameraEnum::COVER_PICTURE_NAME; $cover_exec = 'ffmpeg -i ' . public_path() . '/' . CameraEnum::M3U8_FILE_PATH . $path . '/' . CameraEnum::M3U8_FILE_NAME . ' -vf "select=between(mod(n\, 25)\, 0\, 0), setpts=N/24/TB" ' . public_path() . '/' . CameraEnum::M3U8_FILE_PATH . $path . '/' . $file_name; exec($cover_exec); //判断图片是否存在 $picture_exists = file_exists(public_path() . '/' . CameraEnum::M3U8_FILE_PATH . $path . '/' . $file_name); if ($picture_exists) { $cms = new CameraServices(); //上传图片到oss并更新数据库 $picture_path = $cms->uploadOssFile($file_name, public_path() . '/' . CameraEnum::M3U8_FILE_PATH . $path . '/'); CameraList::where('id', Input::get('camera_id'))->update(['cover_picture' => $picture_path]); } } else { sleep(1); } $i++; } } //海康easy_drawin获取rtsp并推流 public function getRtspByCameraId(){ $result['status'] = true; $result['msg'] = ApiEnum::RETURN_SUCCESS; $query = CameraList::where('id',Input::get('camera_id'))->first(); if (!$query) { $result['status'] = false; $result['msg'] = ApiEnum::NO_CAMERA_URL; return $result; } $degree = MineList::where('id', $query->mine_id)->value('degree'); $mine_list = MineList::whereIn('id', explode('|', $degree))->select(['title'])->get()->toArray(); $path = ''; // foreach ($mine_list as $key => $val) { // $path .= '/' . $val['title']; // } $path = '/'.$mine_list[0]['title']; $new_camera_name = str_replace('-','',$query->camera_name); $new_camera_name = str_replace('#','号',$new_camera_name); $path .= '/' . $new_camera_name; //标记摄像头为在线状态 CameraList::where('id', Input::get('camera_id'))->update(['camera_status' => CameraEnum::CAMERA_STATUS_ONLINE]); //已有拉流id,直接返回拉流链接 if($query->revert_id != 'NullId'){ $result['data'] = [ 'camera_id' => Input::get('camera_id'), 'url' => env('EASY_DARWIN_JF_RTSP') . $path ]; return $result; } if($query->code_stream == 2){ $code_stream = 0; }else{ $code_stream = 1; } $url = $this->artemis.'/api/video/v1/cameras/previewURLs'; $params['cameraIndexCode'] = $query->index_code; $params['streamType'] = $code_stream; //0主码流 1子码流 2第三码流 $params['protocol'] = 'rtsp'; $params['transmode'] = 1; //0:UDP 1:TCP $params['expand'] = 'streamform=rtp'; $this->sign = $this->get_sign($url); $rtsp = $this->curlPost($this->pre_url . $url, json_encode($params)); $rtsp = json_decode($rtsp, true); $data = [ 'url' => $rtsp['data']['url'], 'customPath' => $path, ]; // dd($data); Log::info('请求流媒体服务器参数------------'); Log::info($data); $curl = env('EASY_DARWIN_JF_URL') . CameraEnum::API_STREAM_START . '?' . http_build_query($data); //请求流媒体服务器拉流 $curl_res = curl_request($curl); // DB::table('camera_list')->where('id',$camera_id)->update($res); // dd($res); Log::info('请求流媒体服务器result------------'); Log::info($curl_res); if (strpos($curl_res,' ')) { //切换码流重新获取rtsp if($code_stream == 1){ $code_stream = 0; }else{ $code_stream = 1; } $params['streamType'] = $code_stream; //0主码流 1子码流 2第三码流 $rtsp = $this->curlPost($this->pre_url . $url, json_encode($params)); $rtsp = json_decode($rtsp, true); $data = [ 'url' => $rtsp['data']['url'], 'customPath' => $path, ]; // dd($data); Log::info('请求流媒体服务器参数------------'); Log::info($data); $curl = env('EASY_DARWIN_JF_URL') . CameraEnum::API_STREAM_START . '?' . http_build_query($data); //请求流媒体服务器拉流 $curl_res = curl_request($curl); if(strpos($curl_res,' ')){ //标记摄像头为异常状态 CameraList::where('id', Input::get('camera_id'))->update(['camera_status' => CameraEnum::CAMERA_STATUS_ERROR]); $result['status'] = false; $result['msg'] = ApiEnum::EASY_DAWIN_REQUEST_FAIL; return $result; } } //更新拉流id CameraList::where('id', Input::get('camera_id'))->update( [ 'revert_id' => trim($curl_res, '"'), 'updated_at' => date('Y-m-d H:i:s'), ] ); $result['data'] = [ 'camera_id' => Input::get('camera_id'), 'url' => env('EASY_DARWIN_JF_RTSP') . $path ]; //查询是否存在封面图 $cover_picture = CameraList::where('id', Input::get('camera_id'))->value('cover_picture'); if (!$cover_picture) { if (!is_dir('/www/wwwroot/video.nxjiewei.com/public/' . CameraEnum::M3U8_FILE_PATH . '/' . $path)) { mkdir('/www/wwwroot/video.nxjiewei.com/public/' . CameraEnum::M3U8_FILE_PATH . '/' . $path, 0777, true); } // dd($result_td['content'][0]['url']); $exec = 'nohup /usr/bin/ffmpeg -i "' . $rtsp['data']['url'] . '" -vcodec copy -acodec copy -vbsf h264_mp4toannexb -f hls -hls_flags delete_segments -segment_list_size 10 -hls_list_size 2 /www/wwwroot/video.nxjiewei.com/public/' . CameraEnum::M3U8_FILE_PATH . '/' . $path . '/' . CameraEnum::M3U8_FILE_NAME . ' >/dev/null &'; shell_exec($exec); //sleep10秒生成文件 $i = 1; while ($i <= 10) { //判断m3u8文件是否存在 $file_exists = file_exists(public_path() . '/' . CameraEnum::M3U8_FILE_PATH . $path . '/' . CameraEnum::M3U8_FILE_NAME); //判断ts文件是否存在 $ts_exists = glob(public_path() . '/' . CameraEnum::M3U8_FILE_PATH . $path . '/' . CameraEnum::TS_FILE_SUFFIX); if ($file_exists && $ts_exists) { //获取第一帧作为封面图 $file_name = time() . CameraEnum::COVER_PICTURE_NAME; $cover_exec = 'ffmpeg -i ' . public_path() . '/' . CameraEnum::M3U8_FILE_PATH . $path . '/' . CameraEnum::M3U8_FILE_NAME . ' -vf "select=between(mod(n\, 25)\, 0\, 0), setpts=N/24/TB" ' . public_path() . '/' . CameraEnum::M3U8_FILE_PATH . $path . '/' . $file_name; exec($cover_exec); //判断图片是否存在 $picture_exists = file_exists(public_path() . '/' . CameraEnum::M3U8_FILE_PATH . $path . '/' . $file_name); if ($picture_exists) { $cms = new CameraServices(); //上传图片到oss并更新数据库 $picture_path = $cms->uploadOssFile($file_name, public_path() . '/' . CameraEnum::M3U8_FILE_PATH . $path . '/'); CameraList::where('id', Input::get('camera_id'))->update(['cover_picture' => $picture_path]); } return $result; } else { sleep(1); } $i++; } }else{ return $result; } //标记摄像头为异常状态 CameraList::where('id', Input::get('camera_id'))->update(['camera_status' => CameraEnum::CAMERA_STATUS_ERROR]); $result['status'] = false; $result['msg'] = ApiEnum::EASY_DAWIN_REQUEST_FAIL; return $result; } /** * 以appSecret为密钥,使用HmacSHA256算法对签名字符串生成消息摘要,对消息摘要使用BASE64算法生成签名(签名过程中的编码方式全为UTF-8) */ protected function get_sign($url) { $sign_str = $this->get_sign_str($url); //签名字符串 $priKey = $this->app_secret; $sign = hash_hmac('sha256', $sign_str, $priKey, true); //生成消息摘要 $result = base64_encode($sign); return $result; } /** * 生成签名 * @param $url * @return string */ protected function get_sign_str($url) { // $next = "\n"; $next = "\n"; $str = "POST" . $next . '*/*' . $next . 'application/json' . $next; $str .= "x-ca-key:" . $this->app_key . $next; $str .= "x-ca-timestamp:" . $this->time . $next; $str .= $url; return $str; } /** * 发送请求 * @param string $url * @param string $postData * @param array $options * @return bool|string */ public function curlPost($url = '', $postData = '', $options = array()) { if (is_array($postData)) { $postData = http_build_query($postData); } $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); curl_setopt($ch, CURLOPT_TIMEOUT, 30); //设置cURL允许执行的最长秒数 curl_setopt_array($ch, array( CURLOPT_HTTPHEADER => array( "Accept:" . '*/*', "Content-Type:" . 'application/json', "x-Ca-Key:" . $this->app_key, "X-Ca-Signature:" . $this->sign, "X-Ca-Timestamp:" . $this->time, "X-Ca-Signature-Headers:" . "x-ca-key,x-ca-timestamp", ) )); //https请求 不验证证书和host curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); $data = curl_exec($ch); curl_close($ch); return $data; } }