<?php
/**
 * Created by PhpStorm.
 * User: qiuzijian
 * Date: 2021-04-20
 * Time: 15:33
 */

namespace Modules\Camera\Services;

use App\Enum\ApiEnum;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\Log;
use Modules\Admin\Enum\AdminEnum;
use Modules\Camera\Entities\CameraFieldList;
use Modules\Camera\Entities\CameraList;
use Modules\Camera\Enum\CameraEnum;
use Modules\Camera\Http\Controllers\Api\HaiKangController;
use Modules\Camera\Http\Controllers\Api\TdwyController;
use Modules\Mine\Entities\MineList;
use Modules\Mine\Entities\MineListExt;
use Modules\Mine\Entities\WorkingSurfaceCamera;
use Modules\Mine\Enum\MineEnum;
use Modules\Mine\Services\MineServices;
use OSS\OssClient;
use DB;

class CameraServices
{
    //添加摄像头链接
    public static function addCameraList($params)
    {
        $result['status'] = true;
        $result['msg']    = AdminEnum::RETURN_SUCCESS;
        //通过ip+端口+通道号作为唯一标识判断数据是否存在
        if ($params['ip'] && $params['port'] && $params['com_number']) {
            $query = CameraList::where(
                [
                    'ip'         => $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['pass'],
                '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'],
                'code_stream'    => $params['code_stream'],
                'cover_picture'  => $params['cover_picture'],
                'video_recorder' => $params['video_recorder'],
                '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['video_recorder'] == CameraEnum::VIDEO_RECORDER_HK) {
            if (isset($params['code_stream'])) {
                $code_stream = CameraEnum::CODE_STREAM_TRANS[$params['code_stream']];
            } else {
                $code_stream = 'sub';
            }

            if ($params['user_name'] && $params['pass'] && $params['ip'] && $params['port'] && $params['com_number']) {
                $url  = 'rtsp://' . $params['user_name'] . ':' . $params['pass'] . '@';
                $url .= $params['ip'] . ':' . $params['port'] . '/' . 'h264' . '/' . 'ch' . $params['com_number'] . '/';
                $url .= $code_stream . '/av_stream';  //sub 子码流 main 主码流
            } else {
                $url = '';
            }
        } elseif($params['video_recorder'] == CameraEnum::VIDEO_RECORDER_DH){
            if (isset($params['code_stream'])) {
                $code_stream = CameraEnum::CODE_STREAM_DH[$params['code_stream']];
            } else {
                $code_stream = 'sub';
            }

            if ($params['user_name'] && $params['pass'] && $params['ip'] && $params['port'] && $params['com_number']) {
                $url  = 'rtsp://' . $params['user_name'] . ':' . $params['pass'] . '@';
                $url .= $params['ip'] . ':' . $params['port'] . '/cam/realmonitor?channel=' . $params['com_number'] . '&';
                $url .= 'subtype=' . $code_stream;
            } else {
                $url = '';
            }
        }elseif($params['video_recorder'] == CameraEnum::VIDEO_RECORDER_YS){
            if (isset($params['code_stream'])) {
                $code_stream = CameraEnum::CODE_STREAM_DH[$params['code_stream']];
            } else {
                $code_stream = 'sub';
            }

            if ($params['user_name'] && $params['pass'] && $params['ip'] && $params['port'] && $params['com_number']) {
                $url  = 'rtsp://' . $params['user_name'] . ':' . $params['pass'] . '@';
                $url .= $params['ip'] . ':' . $params['port'] . '/unicast/c' . $params['com_number'] . '/s';
                $url .= $code_stream.'/live';
            } 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 && !$params['cover_picture']) {
                $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['pass'],
                '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'],
                'code_stream'    => $params['code_stream'],
                'cover_picture'  => $params['cover_picture'],
                'video_recorder' => $params['video_recorder'],
                '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',
                'cover_picture',
                'camera_status',
            ]
        )->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;

        //标记摄像头为在线状态
        CameraList::where('id', $camera_id)->update(['camera_status' => CameraEnum::CAMERA_STATUS_ONLINE]);

        //已有拉流id，直接返回拉流链接
        $has_file = file_exists(public_path() . '/' . CameraEnum::M3U8_FILE_PATH . $path . '/' . date('Ymd', time()) . '/' . CameraEnum::M3U8_FILE_NAME);
        if ($has_file) {
            $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,' ')) {
            //标记摄像头为异常状态
            CameraList::where('id', $camera_id)->update(['camera_status' => CameraEnum::CAMERA_STATUS_ERROR]);

            $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(),
        ];

        //sleep10秒生成文件
        $i = 1;
        while ($i <= 10) {
            //判断m3u8文件是否存在
            $file_exists = file_exists(public_path() . '/' . CameraEnum::M3U8_FILE_PATH . $path . '/' . date('Ymd', time()) . '/' . CameraEnum::M3U8_FILE_NAME);
            //判断ts文件是否存在
            $ts_exists = glob(public_path() . '/' . CameraEnum::M3U8_FILE_PATH . $path . '/' . date('Ymd', time()) . '/' . CameraEnum::TS_FILE_SUFFIX);
            //查询是否存在封面图
            $cover_picture = CameraList::where('id', $camera_id)->value('cover_picture');

            if ($file_exists && $ts_exists) {
                //查询是否存在封面图
                if (!$cover_picture) {
                    //获取第一帧作为封面图
                    $file_name = time() . CameraEnum::COVER_PICTURE_NAME;
                    $cover_exec = 'ffmpeg -i ' . public_path() . '/' . CameraEnum::M3U8_FILE_PATH . $path . '/' . date('Ymd', time()) . '/' . CameraEnum::M3U8_FILE_NAME . ' -vf "select=between(mod(n\, 25)\, 0\, 0), setpts=N/24/TB" ' . public_path() . '/' . CameraEnum::M3U8_FILE_PATH . $path . '/' . date('Ymd', time()) . '/' . $file_name;
                    exec($cover_exec);

                    //判断图片是否存在
                    $picture_exists = file_exists(public_path() . '/' . CameraEnum::M3U8_FILE_PATH . $path . '/' . date('Ymd', time()) . '/' . $file_name);

                    if ($picture_exists) {
                        //上传图片到oss并更新数据库
                        $picture_path = self::uploadOssFile($file_name, public_path() . '/' . CameraEnum::M3U8_FILE_PATH . $path . '/' . date('Ymd', time()) . '/');
                        CameraList::where('id', $camera_id)->update(['cover_picture' => $picture_path]);
                    }
                }

                //更新拉流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++;
        }

        //标记摄像头为异常状态
        CameraList::where('id', $camera_id)->update(['camera_status' => CameraEnum::CAMERA_STATUS_ERROR]);

        $result['status'] = false;
        $result['msg']    = ApiEnum::EASY_DAWIN_REQUEST_FAIL;
        return $result;
    }

    //硬盘录像机获取rtsp
    public static function getRtspYingPan($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'];
        }
        $new_camera_name = str_replace('-','',$query->camera_name);
        $new_camera_name = str_replace('#','号',$new_camera_name);
        $path .= '/' . $new_camera_name;

        //标记摄像头为在线状态
        CameraList::where('id', $camera_id)->update(['camera_status' => CameraEnum::CAMERA_STATUS_ONLINE]);

        //已有拉流id，直接返回拉流链接
        if($query->revert_id != 'NullId'){
            $result['data'] = [
                'camera_id' => $camera_id,
                'url' => env('EASY_DARWIN_JF_RTSP') .  $path
            ];
            return  $result;
        }

        $data = [
            'url'        => $query->camera_url,
            'customPath' => $path,
        ];

        Log::info('请求流媒体服务器参数------------');
        Log::info($data);

        $curl = env('EASY_DARWIN_JF_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,' ')) {
            //标记摄像头为异常状态
            CameraList::where('id', $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', $camera_id)->update(
            [
                'revert_id'  => trim($curl_res, '"'),
                'updated_at' => date('Y-m-d H:i:s'),
            ]
        );

        $result['data'] = [
            'camera_id' => $camera_id,
            'url' => env('EASY_DARWIN_JF_RTSP') . $path
        ];

        //查询是否存在封面图
        $cover_picture = CameraList::where('id', $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 "' . $query->camera_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', $camera_id)->update(['cover_picture' => $picture_path]);
                    }

                    return $result;
                } else {
                    sleep(1);
                }

                $i++;
            }
        }else{
            return $result;
        }

        //标记摄像头为异常状态
        CameraList::where('id', $camera_id)->update(['camera_status' => CameraEnum::CAMERA_STATUS_ERROR]);

        $result['status'] = false;
        $result['msg']    = ApiEnum::EASY_DAWIN_REQUEST_FAIL;
        return $result;
    }

    //硬盘录像机获取rtsp
    public static function getCameraUrlByFfmpeg($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;

        //标记摄像头为在线状态
        CameraList::where('id', $camera_id)->update(['camera_status' => CameraEnum::CAMERA_STATUS_ONLINE]);

        //已有拉流id，直接返回拉流链接
        $has_file = file_exists(public_path() . '/' . CameraEnum::M3U8_FILE_PATH . $path . '/' . date('Ymd', time()) . '/' . CameraEnum::M3U8_FILE_NAME);
        if ($has_file) {
            $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;
        }

        if (!is_dir('/www/wwwroot/video.nxjiewei.com/public/' . CameraEnum::M3U8_FILE_PATH . '/' . $path. '/' . date('Ymd', time()))) {
            mkdir('/www/wwwroot/video.nxjiewei.com/public/' . CameraEnum::M3U8_FILE_PATH . '/' . $path. '/' . date('Ymd', time()), 0777, true);
        }
        // dd($result_td['content'][0]['url']);
        $exec = 'nohup /usr/bin/ffmpeg -i "' . $query->camera_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. '/' . date('Ymd', time()) . '/' . 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 . '/' . date('Ymd', time()) . '/' . CameraEnum::M3U8_FILE_NAME . '?' . time(),
        ];

        //sleep10秒生成文件
        $i = 1;
        while ($i <= 10) {
            //判断m3u8文件是否存在
            $file_exists = file_exists(public_path() . '/' . CameraEnum::M3U8_FILE_PATH . $path . '/' . date('Ymd', time()) . '/' . CameraEnum::M3U8_FILE_NAME);
            //判断ts文件是否存在
            $ts_exists = glob(public_path() . '/' . CameraEnum::M3U8_FILE_PATH . $path . '/' . date('Ymd', time()) . '/' . CameraEnum::TS_FILE_SUFFIX);
            //查询是否存在封面图
            $cover_picture = CameraList::where('id', $camera_id)->value('cover_picture');

            if ($file_exists && $ts_exists) {
                //查询是否存在封面图
                if (!$cover_picture) {
                    //获取第一帧作为封面图
                    $file_name = time() . CameraEnum::COVER_PICTURE_NAME;
                    $cover_exec = 'ffmpeg -i ' . public_path() . '/' . CameraEnum::M3U8_FILE_PATH . $path . '/' . date('Ymd', time()) . '/' . CameraEnum::M3U8_FILE_NAME . ' -vf "select=between(mod(n\, 25)\, 0\, 0), setpts=N/24/TB" ' . public_path() . '/' . CameraEnum::M3U8_FILE_PATH . $path . '/' . date('Ymd', time()) . '/' . $file_name;
                    exec($cover_exec);

                    //判断图片是否存在
                    $picture_exists = file_exists(public_path() . '/' . CameraEnum::M3U8_FILE_PATH . $path . '/' . date('Ymd', time()) . '/' . $file_name);

                    if ($picture_exists) {
                        //上传图片到oss并更新数据库
                        $picture_path = self::uploadOssFile($file_name, public_path() . '/' . CameraEnum::M3U8_FILE_PATH . $path . '/' . date('Ymd', time()) . '/');
                        CameraList::where('id', $camera_id)->update(['cover_picture' => $picture_path]);
                    }
                }

                return $result;
            } else {
                sleep(1);
            }

            $i++;
        }

        //标记摄像头为异常状态
        CameraList::where('id', $camera_id)->update(['camera_status' => CameraEnum::CAMERA_STATUS_ERROR]);

        $result['status'] = false;
        $result['msg']    = ApiEnum::EASY_DAWIN_REQUEST_FAIL;
        return $result;
    }

    //根据摄像头id获取摄像头播放链接
    public static function getRtspTianDi($camera_id,$parent_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'];
        }
        $new_camera_name = str_replace('-','',$query->camera_name);
        $new_camera_name = str_replace('#','号',$new_camera_name);
        $path .= '/' . $new_camera_name;
        // dd($path);
        //标记摄像头为在线状态
        CameraList::where('id', $camera_id)->update(['camera_status' => CameraEnum::CAMERA_STATUS_ONLINE]);

        //已有拉流id，直接返回拉流链接
        if($query->revert_id != 'NullId'){
            $result['data'] = [
                'camera_id' => $camera_id,
                'url' => env('EASY_DARWIN_JF_RTSP') .  $path
            ];
            return  $result;
        }



        $mine_ext = MineListExt::where('mine_id', $parent_id)->first();

        Input::replace(
            [
                'url'      => trim($mine_ext->ip, '/') . ':' . $mine_ext->port,
                'username' => $mine_ext->key,
                'password' => $mine_ext->secret,
                'sysId'    => 'PG',
                'sId'      => $query->index_code,
                'ip'       => trim(trim($query->ip, 'http://'), 'https://'),
                'port'     => $query->port,
            ]
        );

        $tdwy = new TdwyController();
        $result_td = $tdwy->getRtspById();


        $data = [
            'url'        => $result_td['content'][0]['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,' ')) {
            //标记摄像头为异常状态
            CameraList::where('id', $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', $camera_id)->update(
            [
                'revert_id'  => trim($curl_res, '"'),
                'updated_at' => date('Y-m-d H:i:s'),
            ]
        );

        $result['data'] = [
            'camera_id' => $camera_id,
            'url' => env('EASY_DARWIN_JF_RTSP') . $path
        ];

        //查询是否存在封面图
        $cover_picture = CameraList::where('id', $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 "' . $result_td['content'][0]['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', $camera_id)->update(['cover_picture' => $picture_path]);
                    }

                    return $result;
                } else {
                    sleep(1);
                }

                $i++;
            }
        }else{
            return $result;
        }

        //标记摄像头为异常状态
        CameraList::where('id', $camera_id)->update(['camera_status' => CameraEnum::CAMERA_STATUS_ERROR]);

        $result['status'] = false;
        $result['msg']    = ApiEnum::EASY_DAWIN_REQUEST_FAIL;

        return $result;
    }

    //海康获取rtsp流
    public static function getHkRtsp($camera_id,$parent_id)
    {
        $mine_ext = DB::table('mine_list_ext')->where('mine_id',$parent_id)->get();

        Input::replace(
            [
                'url'      => trim($mine_ext[0]->ip, '/') . ':' . $mine_ext[0]->port,
                'key' => $mine_ext[0]->key,
                'secret' => $mine_ext[0]->secret,
                'camera_id' => $camera_id,
                'parent_id' => $parent_id,
            ]
        );

        $haikang = new HaiKangController();
        $result = $haikang->getHikRtsp();
        return $result;
    }

    //根据摄像头id获取摄像头播放链接
    public static function getRtspHaiKang($camera_id,$parent_id)
    {
        $mine_ext = DB::table('mine_list_ext')->where('mine_id',$parent_id)->get();

        Input::replace(
            [
                'url'      => trim($mine_ext[0]->ip, '/') . ':' . $mine_ext[0]->port,
                'key' => $mine_ext[0]->key,
                'secret' => $mine_ext[0]->secret,
                'camera_id' => $camera_id,
                'parent_id' => $parent_id,
            ]
        );

        $haikang = new HaiKangController();
        $result = $haikang->getRtspByCameraId();
        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);
        }

        //金凤easy清流
        $data_jf = [
//            'start' => 0,
//            'limit' => 100,
        ];
        $curl_jf = env('EASY_DARWIN_JF_URL') . CameraEnum::API_PUSHERS . '?' . http_build_query($data_jf);

        //请求流媒体服务器获取推流列表
        $curl_res_jf = curl_request($curl_jf);

        $curl_res_jf = json_decode($curl_res_jf, true);

        $success_jf = 0;

        if ($curl_res_jf['total'] > 0) {
            //根据返回id调停止推流接口
            foreach ($curl_res_jf['rows'] as $key => $val) {
                $data = [
                    'id' => $val['id']
                ];

                $curl = env('EASY_DARWIN_JF_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_jf++;
                } else {
                    Log::info('流媒体服务器停止推流失败id:' . $val['id']);
                    Log::info('流媒体服务器停止推流失败返回结果');
                    Log::info($stop_res);
                }
            }
        }

        if ($success_jf == $curl_res_jf['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'),
                ]
            );
        }


        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');

        //标记摄像头为在线状态
        CameraList::where('id', $camera_id)->update(['camera_status' => CameraEnum::CAMERA_STATUS_ONLINE]);
        
        //如果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;
        }

        if ($camera->video_recorder == CameraEnum::VIDEO_RECORDER_HK) {  //海康视频逻辑
            Input::replace(
                [
                    'url'             => trim($query->ip, '/') . ':' . $query->port,
                    'key'             => $query->key,
                    'secret'          => $query->secret,
                    'cameraIndexCode' => $camera->index_code,
                    'streamType'      => CameraEnum::CODE_STREAM_HAK[$camera->code_stream],
                    'protocol'        => 'rtmp'
                ]
            );
            $haikang   = new HaiKangController();
            $result_hk = $haikang->getCamerasUrl();

            if ($result_hk['data']['url']) {
                //先取当前码流
                $res = self::getVideoStream($result_hk['data']['url'], $path, $camera_id);

                if (!$res) {
                    $code_stream = self::exchangCodeStream($camera->code_stream);
                    Input::replace(
                        [
                            'url'             => trim($query->ip, '/') . ':' . $query->port,
                            'key'             => $query->key,
                            'secret'          => $query->secret,
                            'cameraIndexCode' => $camera->index_code,
                            'streamType'      => CameraEnum::CODE_STREAM_HAK[$code_stream],
                            'protocol'        => 'rtmp',
                        ]
                    );
                    $haikang   = new HaiKangController();
                    $result_hk_2 = $haikang->getCamerasUrl();

                    if (!$result_hk_2['data']['url']) {
                        //标记摄像头为异常状态
                        CameraList::where('id', $camera_id)->update(['camera_status' => CameraEnum::CAMERA_STATUS_ERROR]);

                        $result['status'] = false;
                        $result['msg'] = ApiEnum::HK_REQUEST_FAIL;
                        return $result;
                    }

                    $res = self::getVideoStream($result_hk_2['data']['url'], $path, $camera_id);

                    if (!$res) {
                        //标记摄像头为异常状态
                        CameraList::where('id', $camera_id)->update(['camera_status' => CameraEnum::CAMERA_STATUS_ERROR]);

                        $result['status'] = false;
                        $result['msg'] = ApiEnum::HK_REQUEST_FAIL;
                        return $result;
                    } else {
                        //更新视频码流
                        CameraList::where('id', $camera_id)->update(['code_stream' => $code_stream]);
                        $result['data'] = $res['data'];
                    }
                } else {
                    $result['data'] = $res['data'];
                }
            } else {  //直接获取rtmp失败时切换码流重新获取
                $code_stream = self::exchangCodeStream($camera->code_stream);
                Input::replace(
                    [
                        'url'             => trim($query->ip, '/') . ':' . $query->port,
                        'key'             => $query->key,
                        'secret'          => $query->secret,
                        'cameraIndexCode' => $camera->index_code,
                        'streamType'      => CameraEnum::CODE_STREAM_HAK[$code_stream],
                        'protocol'        => 'rtmp',
                    ]
                );
                $haikang   = new HaiKangController();
                $result_hk_2 = $haikang->getCamerasUrl();

                if (!$result_hk_2['data']['url']) {
                    //标记摄像头为异常状态
                    CameraList::where('id', $camera_id)->update(['camera_status' => CameraEnum::CAMERA_STATUS_ERROR]);

                    $result['status'] = false;
                    $result['msg'] = ApiEnum::HK_REQUEST_FAIL;
                    return $result;
                }

                $res = self::getVideoStream($result_hk_2['data']['url'], $path, $camera_id);

                if (!$res) {
                    //标记摄像头为异常状态
                    CameraList::where('id', $camera_id)->update(['camera_status' => CameraEnum::CAMERA_STATUS_ERROR]);

                    $result['status'] = false;
                    $result['msg'] = ApiEnum::HK_REQUEST_FAIL;
                    return $result;
                } else {
                    //更新视频码流
                    CameraList::where('id', $camera_id)->update(['code_stream' => $code_stream]);
                    $result['data'] = $res['data'];
                }
            }
        } else if ($camera->video_recorder == CameraEnum::VIDEO_RECORDER_TD) {  //天地伟业视频逻辑
            Input::replace(
                [
                    'url'      => trim($query->ip, '/') . ':' . $query->port,
                    'username' => $query->key,
                    'password' => $query->secret,
                    'sysId'    => 'PG',
                    'sId'      => $camera->index_code,
                    'ip'       => trim(trim($camera->ip, 'http://'), 'https://'),
                    'port'     => $camera->port,
                ]
            );

            $tdwy = new TdwyController();
            $result_td = $tdwy->getRtspById();

            if ($result_td['statusCode'] == CameraEnum::TDWY_API_STATUS_CODE_SUCCSS && $result_td['content']) {
                //执行取流动作
                $res = self::getVideoStream($result_td['content'][0]['url'], $path, $camera_id);

                if (!$res) {
                    //标记摄像头为异常状态
                    CameraList::where('id', $camera_id)->update(['camera_status' => CameraEnum::CAMERA_STATUS_ERROR]);

                    $result['status'] = false;
                    $result['msg'] = ApiEnum::HK_REQUEST_FAIL;
                    return $result;
                } else {
                    $result['data'] = $res['data'];
                }
            } else {
                //标记摄像头为异常状态
                CameraList::where('id', $camera_id)->update(['camera_status' => CameraEnum::CAMERA_STATUS_ERROR]);

                $result['status'] = false;
                $result['msg'] = ApiEnum::HK_REQUEST_FAIL;
                return $result;
            }
        } else {
            $result['status'] = false;
            $result['msg'] = ApiEnum::NONEXISTENT_VIDEO_RECORDER;
            return $result;
        }

        return $result;
    }

    //获取视频流
    public static function getVideoStream($video_url, $path, $camera_id)
    {
        $result = [];

        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);
        }

//        $mine_list = DB::table('mine_list')
//            ->select('mine_list.degree')
//            ->leftJoin('camera_list','camera_list.mine_id','=','mine_list.id')
//            ->where('camera_list.id',$camera_id)->get();
//        if(isset($mine_list)){
//            $mine_id = explode('|',$mine_list[0]->degree)[0];
//            $mine_res = DB::table('mine_list')->where('id',$mine_id)->get();
//        }
//        //取流进程
//        if(isset($mine_res[0]->title) && in_array($mine_res[0]->title,config('mine'))){
//            $exec = 'nohup /usr/bin/ffmpeg -rtsp_transport tcp -i "' . $video_url . '" -b:v 200k -c:v libx264 -c:a copy -s 384*288 -vbsf h264_mp4toannexb -f hls -hls_flags delete_segments -segment_list_size 10 -hls_list_size 2 -threads 4 /www/wwwroot/video.nxjiewei.com/public/' . CameraEnum::M3U8_FILE_PATH . '/' . $path . '/' . CameraEnum::M3U8_FILE_NAME . ' >/dev/null &';
//        }else{
            $exec = 'nohup /usr/bin/ffmpeg -i "' . $video_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 &';
//        }

        //取流进程
//        $exec = 'nohup /usr/bin/ffmpeg -i "' . $video_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 &';

//        $exec = 'nohup /usr/bin/ffmpeg -rtsp_transport tcp -i "' . $video_url . '" -b:v 200k -c:v libx264 -c:a copy -s 384*288 -vbsf h264_mp4toannexb -f hls -hls_flags delete_segments -segment_list_size 10 -hls_list_size 2 -threads 4 /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);

            //查询是否存在封面图
            $cover_picture = CameraList::where('id', $camera_id)->value('cover_picture');

            if ($file_exists && $ts_exists) {
                //查询是否存在封面图
                if (!$cover_picture) {
                    //获取第一帧作为封面图
                    $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) {
                        //上传图片到oss并更新数据库
                        $picture_path = self::uploadOssFile($file_name, public_path() . '/' . CameraEnum::M3U8_FILE_PATH . '/' . $path . '/');
                        CameraList::where('id', $camera_id)->update(['cover_picture' => $picture_path]);
                    }
                }

                $result['data'] = [
                    'camera_id' => $camera_id,
                    'url' => env('VIDEO_SYSTEM_URL') . CameraEnum::M3U8_FILE_PATH . '/' . $path . '/' . CameraEnum::M3U8_FILE_NAME . '?' . time(),
                ];

                CameraList::where('id', $camera_id)->update(['revert_id' => CameraEnum::CAMERA_FILE_EXIST]);

                return $result;
            } else {
                sleep(1);
            }

            $i++;
        }

        return false;
    }

    //切换视频码流
    public static function exchangCodeStream($code_stream)
    {
        $return_code = CameraEnum::CODE_STREAM_MAIN;

        //子码流切主码流
        if ($code_stream == CameraEnum::CODE_STREAM_SUB) {
            $return_code = CameraEnum::CODE_STREAM_MAIN;
        }

        //主码流切子码流
        if ($code_stream == CameraEnum::CODE_STREAM_MAIN) {
            $return_code = CameraEnum::CODE_STREAM_SUB;
        }

        return $return_code;
    }

    //获取内网服务器摄像头播放地址
    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;
    }

    //上传文件到本地
    public static function uploadFile($file)
    {
        $destinationPath = public_path() . '/filedownload/';
        $extension       = $file->getClientOriginalExtension();
        $fileName        = time() . '.' . $extension;
        $file->move($destinationPath, $fileName);
        return $fileName;
    }

    //oss上传文件
    public static function uploadOssFile($file_name, $file_path)
    {
        try{
            $oss = new OssClient(
                Config::get('filesystems.disks.oss_view.access_key'),
                Config::get('filesystems.disks.oss_view.secret_key'),
                Config::get('filesystems.disks.oss_view.endpoint')
            );

            $res = $oss->uploadFile(Config::get('filesystems.disks.oss_view.bucket'), '摄像头封面/oss-' . $file_name, $file_path . $file_name);
        } catch(OssException $e) {
            printf(__FUNCTION__ . ": FAILED\n");
            printf($e->getMessage() . "\n");
            return;
        }

        if (isset($res['info']['url']) && $res['info']['url']) {
            return urldecode($res['info']['url']);
        } else {
            return false;
        }
    }

    //删除临时上传文件
    public static function delUploadFile($delDir = FALSE)
    {
        $path = public_path() . '/filedownload/';

        $handle = opendir($path);
        if ($handle) {
            while (false !== ( $item = readdir($handle) )) {
                if ($item != "." && $item != "..")
                    is_dir("$path/$item") ? delDirAndFile("$path/$item", $delDir) : unlink("$path/$item");
            }
            closedir($handle);
            if ($delDir)
                return rmdir($path);
        }else {
            if (file_exists($path)) {
                return unlink($path);
            } else {
                return FALSE;
            }
        }
    }

}