$params['ip'], 'port' => $params['port'], 'com_number' => $params['com_number'], ] )->first(); if ($query) { $result['status'] = false; $result['msg'] = AdminEnum::RECORD_ALREADY_EXIST; return $result; } } if ($params['camera_source'] == CameraEnum::CAMERA_SOURCE_3) { $camera_url = $params['camera_url']; } else { $camera_url = self::makeCameraUrl($params); } //入库动作 $res = CameraList::insert( [ 'mine_id' => $params['mine_id'], 'ip' => $params['ip'], 'port' => $params['port'], 'user_name' => $params['user_name'], 'password' => $params['password'], 'com_number' => $params['com_number'], 'camera_name' => $params['camera_name'], 'revert_id' => CameraEnum::CAMERA_DEFAULT_REVERT_ID, // 'status' => $params['status'], 'camera_url' => $camera_url, 'sort' => $params['sort'], 'camera_type' => $params['camera_type'], 'camera_source' => $params['camera_source'], 'created_at' => date('Y-m-d H:i:s'), 'updated_at' => date('Y-m-d H:i:s'), ] ); if (!$res) { $result['status'] = false; $result['msg'] = AdminEnum::DATABASE_ERROR; } return $result; } //生成摄像头请求链接 public static function makeCameraUrl($params) { if ($params['user_name'] && $params['password'] && $params['ip'] && $params['port'] && $params['com_number']) { $url = 'rtsp://' . $params['user_name'] . ':' . $params['password'] . '@'; $url .= $params['ip'] . ':' . $params['port'] . '/' . 'h264' . '/' . 'ch' . $params['com_number'] . '/'; $url .= 'sub/av_stream'; //sub 子码流 // $url .= 'main/av_stream'; //main 主码流 } else { $url = ''; } return $url; } //编辑摄像头链接 public static function editCameraList($params) { $result['status'] = true; $result['msg'] = AdminEnum::RETURN_SUCCESS; if ($params['camera_source'] == CameraEnum::CAMERA_SOURCE_3) { $camera_url = $params['camera_url']; } else { $camera_url = self::makeCameraUrl($params); } //判断记录是否存在 $query = CameraList::find($params['id']); if (!$query) { $result['status'] = false; $result['msg'] = AdminEnum::RECORD_NOT_EXIST; return $result; } //通过ip+端口+通道号作为唯一标识判断数据是否存在 if ($params['ip'] && $params['port'] && $params['com_number']) { $query = CameraList::where( [ 'ip' => $params['ip'], 'port' => $params['port'], 'com_number' => $params['com_number'], ] )->where('id', '!=', $params['id'])->first(); if ($query) { $result['status'] = false; $result['msg'] = AdminEnum::RECORD_ALREADY_EXIST; return $result; } } //更新动作 $res = CameraList::where('id', $params['id'])->update( [ 'mine_id' => $params['mine_id'], 'ip' => $params['ip'], 'port' => $params['port'], 'user_name' => $params['user_name'], 'password' => $params['password'], 'com_number' => $params['com_number'], 'camera_name' => $params['camera_name'], // 'status' => $params['status'], 'camera_url' => $camera_url, 'sort' => $params['sort'], 'camera_type' => $params['camera_type'], 'camera_source' => $params['camera_source'], 'updated_at' => date('Y-m-d H:i:s'), ] ); if (!$res) { $result['status'] = false; $result['msg'] = AdminEnum::DATABASE_ERROR; } return $result; } //删除摄像头列表记录 public static function delCameraList($params) { $result['status'] = true; $result['msg'] = AdminEnum::RETURN_SUCCESS; //判断字段是否存在 $query = CameraList::find($params['id']); if (!$query) { $result['status'] = false; $result['msg'] = AdminEnum::RECORD_NOT_EXIST; return $result; } $res = CameraList::where('id', $params['id'])->delete(); if (!$res) { $result['status'] = false; $result['msg'] = AdminEnum::DATABASE_ERROR; } return $result; } //添加摄像头链接生成字段 public static function addCameraFieldList($params) { $result['status'] = true; $result['msg'] = AdminEnum::RETURN_SUCCESS; //判断字段是否已存在 $query = CameraFieldList::where('field_name', $params['field_name'])->first(); if ($query) { $result['status'] = false; $result['msg'] = AdminEnum::RECORD_ALREADY_EXIST; return $result; } //入库动作 $res = CameraFieldList::insert( [ 'field_name' => $params['field_name'], 'created_at' => date('Y-m-d H:i:s'), 'updated_at' => date('Y-m-d H:i:s'), ] ); if (!$res) { $result['status'] = false; $result['msg'] = AdminEnum::DATABASE_ERROR; } return $result; } //编辑摄像头链接生成字段 public static function editCameraFieldList($params) { $result['status'] = true; $result['msg'] = AdminEnum::RETURN_SUCCESS; //判断字段是否存在 $query = CameraFieldList::find($params['id']); if (!$query) { $result['status'] = false; $result['msg'] = AdminEnum::RECORD_NOT_EXIST; return $result; } $res = CameraFieldList::where('id', $params['id'])->update( [ 'field_name' => $params['field_name'], 'updated_at' => date('Y-m-d H:i:s'), ] ); if (!$res) { $result['status'] = false; $result['msg'] = AdminEnum::DATABASE_ERROR; } return $result; } //删除摄像头链接生成字段 public static function delCameraFieldList($params) { $result['status'] = true; $result['msg'] = AdminEnum::RETURN_SUCCESS; //判断字段是否存在 $query = CameraFieldList::find($params['id']); if (!$query) { $result['status'] = false; $result['msg'] = AdminEnum::RECORD_NOT_EXIST; return $result; } $res = CameraFieldList::where('id', $params['id'])->delete(); if (!$res) { $result['status'] = false; $result['msg'] = AdminEnum::DATABASE_ERROR; } return $result; } //根据矿区id获取摄像头列表 public static function getCameraListByMineId($mine_id, $camera_type = CameraEnum::CAMERA_TYPE_ALL, $parent_id, $surface_id = '') { $result['status'] = true; $result['msg'] = ApiEnum::RETURN_SUCCESS; $query = CameraList::where('is_show', CameraEnum::IS_SHOW_YES)->orderBy('sort', 'desc'); if ($camera_type && $camera_type != CameraEnum::CAMERA_TYPE_ALL) { $query = $query->where('camera_type', $camera_type); } $query = $query->select( [ 'id as camera_id', 'mine_id', 'camera_name' ] )->get()->toArray(); $surface_camera = []; if ($surface_id) { $surface_camera = WorkingSurfaceCamera::where('surface_id', $surface_id)->pluck('camera_id')->all(); } $arr = []; foreach ($query as $key => $val) { if ($surface_id && !in_array($val['camera_id'], $surface_camera)) { continue; } $val['parent_id'] = $parent_id; if ($camera_type && !in_array($camera_type, [CameraEnum::CAMERA_TYPE_ALL, CameraEnum::CAMERA_TYPE_NORMAL])) { $degree = MineList::where('id', $val['mine_id'])->value('degree'); if ($mine_id == explode('|', $degree)[0]) { $arr[] = $val; } } else { if ($mine_id == $val['mine_id']) { $arr[] = $val; } } } $result['data'] = $arr; return $result; } //根据摄像头id获取摄像头播放链接 public static function getCameraUrlByCameraId($camera_id) { $result['status'] = true; $result['msg'] = ApiEnum::RETURN_SUCCESS; $query = CameraList::where('id', $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 .= '/' . $query->camera_name . $camera_id; //已有拉流id,直接返回拉流链接 if ($query->revert_id != CameraEnum::CAMERA_DEFAULT_REVERT_ID) { $result['data'] = [ 'camera_id' => $camera_id, 'url' => env('VIDEO_SYSTEM_URL') . CameraEnum::M3U8_FILE_PATH . $path . '/' . date('Ymd', time()) . '/' . CameraEnum::M3U8_FILE_NAME . '?' . time(), ]; return $result; } $data = [ 'url' => $query->camera_url, 'customPath' => $path, ]; Log::info('请求流媒体服务器参数------------'); Log::info($data); $curl = env('EASY_DARWIN_URL') . CameraEnum::API_STREAM_START . '?' . http_build_query($data); //请求流媒体服务器拉流 $curl_res = curl_request($curl); Log::info('请求流媒体服务器result------------'); Log::info($curl_res); if (strpos($curl_res,' ')) { $result['status'] = false; $result['msg'] = ApiEnum::EASY_DAWIN_REQUEST_FAIL; return $result; } $result['data'] = [ 'camera_id' => $camera_id, 'url' => env('VIDEO_SYSTEM_URL') . CameraEnum::M3U8_FILE_PATH . $path . '/' . date('Ymd', time()) . '/' . CameraEnum::M3U8_FILE_NAME . '?' . time(), ]; $i = 1; while ($i <= 10) { $file_exists = file_exists(public_path() . '/' . CameraEnum::M3U8_FILE_PATH . $path . '/' . date('Ymd', time()) . '/' . CameraEnum::M3U8_FILE_NAME); if ($file_exists) { //更新拉流id CameraList::where('id', $camera_id)->update( [ 'revert_id' => trim($curl_res, '"'), 'updated_at' => date('Y-m-d H:i:s'), ] ); return $result; } else { sleep(1); } $i++; } $result['status'] = false; $result['msg'] = ApiEnum::EASY_DAWIN_REQUEST_FAIL; return $result; } //停止流媒体推流 public static function stopCameraStream() { $result['status'] = true; $result['msg'] = ApiEnum::RETURN_SUCCESS; //先查询流媒体推流列表 $data = [ // 'start' => 0, // 'limit' => 100, ]; $curl = env('EASY_DARWIN_URL') . CameraEnum::API_PUSHERS . '?' . http_build_query($data); //请求流媒体服务器获取推流列表 $curl_res = curl_request($curl); $curl_res = json_decode($curl_res, true); $success = 0; if ($curl_res['total'] > 0) { //根据返回id调停止推流接口 foreach ($curl_res['rows'] as $key => $val) { $data = [ 'id' => $val['id'] ]; $curl = env('EASY_DARWIN_URL') . CameraEnum::API_STREAM_STOP . '?' . http_build_query($data); //请求流媒体服务器停止推流 $stop_res = curl_request($curl); $stop_res = json_decode($stop_res, true); if ($stop_res == 'OK') { //更新拉流id为默认id CameraList::where('revert_id', $val['id'])->update( [ 'revert_id' => CameraEnum::CAMERA_DEFAULT_REVERT_ID, 'updated_at' => date('Y-m-d H:i:s'), ] ); $success++; } else { Log::info('流媒体服务器停止推流失败id:' . $val['id']); Log::info('流媒体服务器停止推流失败返回结果'); Log::info($stop_res); } } } if ($success == $curl_res['total']) { CameraList::where('revert_id', '!=', CameraEnum::CAMERA_DEFAULT_REVERT_ID)->update( [ 'revert_id' => CameraEnum::CAMERA_DEFAULT_REVERT_ID, 'updated_at' => date('Y-m-d H:i:s'), ] ); } //清空海康视频服务器已存在id CameraList::where('revert_id', CameraEnum::CAMERA_FILE_EXIST)->update(['revert_id' => CameraEnum::CAMERA_DEFAULT_REVERT_ID]); //递归删除目录 $dir = public_path() . '/files/video/m3u8/'; if (is_dir($dir)) { deldir($dir); } return $result; } //查询海康矿井摄像头列表 public static function getHaiKangCamera($parent_id, $mine_id, $camera_type) { $result['status'] = true; $result['msg'] = ApiEnum::RETURN_SUCCESS; $result['data'] = []; if ($camera_type != CameraEnum::CAMERA_TYPE_ALL) { return $result; } $query = MineListExt::where('mine_id', $parent_id)->first(); $list = []; Input::replace( [ 'url' => trim($query->ip, '/') . ':' . $query->port, 'key' => $query->key, 'secret' => $query->secret, 'indexCode' => $mine_id, ] ); $haikang = new HaiKangController(); $result_hk = $haikang->getCamerasList(); if ($result_hk['data']['list']) { foreach ($result_hk['data']['list'] as $key => $val) { $list[$key]['mine_id'] = $mine_id; $list[$key]['camera_id'] = $val['cameraIndexCode']; $list[$key]['camera_name'] = $val['cameraName']; $list[$key]['trans_code'] = $val['encodeDevIndexCode']; $list[$key]['com_number'] = $val['channelNo']; } } $result['data'] = $list; return $result; } //查询海康摄像头编码设备列表 public static function getHaiKangTransList($parent_id) { $result['status'] = true; $result['msg'] = ApiEnum::RETURN_SUCCESS; $result['data'] = []; $query = MineListExt::where('mine_id', $parent_id)->first(); //先获取编码设备列表 Input::replace( [ 'url' => trim($query->ip, '/') . ':' . $query->port, 'key' => $query->key, 'secret' => $query->secret, ] ); $haikang = new HaiKangController(); $result_hk = $haikang->getTranscodeList(); if ($result_hk['data']['list']) { $result['data'] = $result_hk['data']['list']; } return $result; } //查询海康矿井摄像头播放链接 public static function getHaiKangCameraUrl($parent_id, $camera_id) { $result['status'] = true; $result['msg'] = ApiEnum::RETURN_SUCCESS; $result['data'] = []; $query = MineListExt::where('mine_id', $parent_id)->first(); $slug = MineList::where('id', $parent_id)->value('slug'); $count = strpos($slug, 'MeiKuang'); if ($count) { $slug = substr_replace($slug, '', $count, 8); } $slug = strtolower($slug); Input::replace( [ 'url' => trim($query->ip, '/') . ':' . $query->port, 'key' => $query->key, 'secret' => $query->secret, 'cameraIndexCode' => $camera_id, ] ); $haikang = new HaiKangController(); $result_hk = $haikang->getCamerasUrl(); if ($result_hk['data']['url']) { $url = CameraEnum::VIDEO_AGENCY_URL . $slug . '/video/' . strstr($result_hk['data']['url'], 'openUrl'); $result['data']['camera_id'] = $camera_id; $result['data']['url'] = $url; } return $result; } //查询海康矿井摄像头列表 public static function getHaiKangTransCode($parent_id) { $result['status'] = true; $result['msg'] = ApiEnum::RETURN_SUCCESS; $result['data'] = []; $query = MineListExt::where('mine_id', $parent_id)->first(); Input::replace( [ 'url' => trim($query->ip, '/') . ':' . $query->port, 'key' => $query->key, 'secret' => $query->secret, ] ); $haikang = new HaiKangController(); $result_hk = $haikang->getTranscodeInfo(); if ($result_hk) { $result['data'] = json_decode($result_hk, true); } return $result; } //获取大南湖监控列表 public static function getLeChangeCamera() { $result['status'] = true; $result['msg'] = ApiEnum::RETURN_SUCCESS; $token = self::getLeChangeToken(); if (!$token) { $result['status'] = false; $result['msg'] = ApiEnum::LECHANGE_REQUEST_FAIL; return $result; } $url = CameraEnum::LIVE_LIST_URL; $params = [ 'token' => $token, 'queryRange' => '1-10', ]; $data = self::getLeChangeSign($params); $ch = curl_init(); $res = curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $curl_res = curl_exec($ch); curl_close($ch); $curl_res = json_decode(iconv('utf-8', 'UTF-8', $curl_res), true); if ($curl_res == null || $curl_res['result']['msg'] != CameraEnum::LECHANGE_API_SUCCESS) { $result['status'] = false; $result['msg'] = ApiEnum::LECHANGE_REQUEST_FAIL; return $result; } foreach ($curl_res['result']['data']['lives'] as $key => $val) { $result['data'][$key] = [ 'camera_name' => $val['deviceId'], 'camera_url' => $val['streams'][3]['hls'] ]; } return $result; } //乐橙获取access_token public static function getLeChangeToken() { if (Cache::has(CameraEnum::ACCESS_TOKEN_CACHE_KEY)) { return Cache::get(CameraEnum::ACCESS_TOKEN_CACHE_KEY); } $url = CameraEnum::ACCESS_TOKEN_URL; $data = self::getLeChangeSign(); $ch = curl_init(); $res = curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $result = curl_exec($ch); curl_close($ch); $result = json_decode(nl2br(iconv('utf-8', 'UTF-8', $result)), true); if ($result == null || $result['result']['msg'] != CameraEnum::LECHANGE_API_SUCCESS) { return false; } $token = $result['result']['data']['accessToken']; $time = substr($result['result']['data']['expireTime'], 0, 2) . '0000'; Cache::put(CameraEnum::ACCESS_TOKEN_CACHE_KEY, $token, $time); return $token; } //乐橙数据接口验签 private static function getLeChangeSign($params = []) { $time = strtotime(date('Y-m-d H:i:s', time())); $nonce = md5(time()); $appId = CameraEnum::LECHANGE_APPID; $appSecret = CameraEnum::LECHANGE_APPSECRET; $signStr = "time:$time,nonce:$nonce,appSecret:$appSecret"; $sign = md5($signStr); $data = json_encode( [ 'system' => [ 'ver' => '1.0', 'sign' => $sign, 'appId' => $appId, 'time' => $time, 'nonce' => $nonce ], 'params' => empty($params) ? new \stdClass() : $params, 'id' => '88' ] ); return $data; } //通过rtmp同步m3u8文件并返回url public static function downloadCameraFiles($parent_id, $camera_id) { $result['status'] = true; $result['msg'] = ApiEnum::RETURN_SUCCESS; $query = MineListExt::where('mine_id', $parent_id)->first(); $camera = CameraList::find($camera_id); $degree = MineList::where('id', $camera->mine_id)->value('degree'); $degree = explode('|', $degree); $path = ''; foreach ($degree as $key => $val) { $path .= MineList::where('id', $val)->value('title') . '/'; } $path .= $camera->camera_name . '/' . date('Ymd'); //如果m3u8文件已拉取,直接返回播放链接 if ($camera->revert_id == CameraEnum::CAMERA_FILE_EXIST) { $result['data'] = [ 'camera_id' => $camera_id, 'url' => env('VIDEO_SYSTEM_URL') . CameraEnum::M3U8_FILE_PATH . '/' . $path . '/' . CameraEnum::M3U8_FILE_NAME . '?' . time(), ]; return $result; } Input::replace( [ 'url' => trim($query->ip, '/') . ':' . $query->port, 'key' => $query->key, 'secret' => $query->secret, 'cameraIndexCode' => $camera->index_code, 'protocol' => 'rtmp', ] ); $haikang = new HaiKangController(); $result_hk = $haikang->getCamerasUrl(); if ($result_hk['data']['url']) { mkdir('/www/wwwroot/video.nxjiewei.com/public/' . CameraEnum::M3U8_FILE_PATH . '/' . $path, 0777, true); $exec = 'nohup /usr/bin/ffmpeg -i ' . $result_hk['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); $result['data'] = [ 'camera_id' => $camera_id, 'url' => env('VIDEO_SYSTEM_URL') . CameraEnum::M3U8_FILE_PATH . '/' . $path . '/' . CameraEnum::M3U8_FILE_NAME . '?' . time(), ]; $i = 1; while ($i <= 10) { $file_exists = file_exists(public_path() . '/' . CameraEnum::M3U8_FILE_PATH . '/' . $path . '/' . CameraEnum::M3U8_FILE_NAME); if ($file_exists) { CameraList::where('id', $camera_id)->update(['revert_id' => CameraEnum::CAMERA_FILE_EXIST]); return $result; } else { sleep(1); } $i++; } $result['status'] = false; $result['msg'] = ApiEnum::HK_REQUEST_FAIL; return $result; } else { $result['status'] = false; $result['msg'] = ApiEnum::HK_REQUEST_FAIL; } return $result; } //获取内网服务器摄像头播放地址 public static function getIntranetCameraUrl($camera_id) { $result['status'] = true; $result['msg'] = ApiEnum::RETURN_SUCCESS; $camera_url = CameraList::where('id', $camera_id)->value('camera_url'); if (!$camera_url) { $result['status'] = false; $result['msg'] = ApiEnum::NO_CAMERA_URL; return $result; } $result['data'] = [ 'camera_id' => $camera_id, 'url' => rtrim($camera_url, '/') . '/' . date('Ymd', time()) . '/' . CameraEnum::M3U8_FILE_NAME ]; return $result; } }