给ZLMediaKit添加一个录制MP4文件自动转HLS的功能!
其中ZLMediakit的Server是支持动态添加摄像头,为了简单使用,这里增加一个静态增加摄像头的能力,给config.ini文件添加一个camera一节:
[camera] #配置默认拉取的监控摄像头地址,对应的点播地址为:http://192.168.1.100:8090/live/chn1/hls.m3u8 http://192.168.1.100:8090/live/chn2/hls.m3u8 number=1 ip_1=rtsp://hkws_media:344444!@192.168.1.103:554/Streaming/Channels/102?transportmode=unicast&profile=Profile_2 ip_2=rtsp://admin:444444@192.168.1.104:554/h264/ch1/sub/av_stream
修改main.cpp增加自动监控采集,并添加录制视频转hls功能:
//add for camera.默认加载的摄像头地址信息配置 namespace CameraConfig{ #define CAMERA_FIELD "camera." const string number = CAMERA_FIELD"number"; const string ip = CAMERA_FIELD"ip_"; } //默认加载的摄像头地址信息配置 namespace CameraConfig{ #define CAMERA_FIELD "camera." const string number = CAMERA_FIELD"number"; const string ip = CAMERA_FIELD"ip_"; } static map<string, PlayerProxy::Ptr> mGlobalProxyMap; static void startMonitorRecord(){ //kBroadcastRecordMP4 NoticeCenter::Instance().addListener(nullptr,Broadcast::kBroadcastRecordMP4,[](BroadcastRecordMP4Args){ std::string strFilePath = info.strFilePath; std::string strFileName = info.strFileName; std::string strFolder = info.strFolder; std::string strUrl = info.strUrl; std::string strAppName = info.strAppName; std::string strStreamId = info.strStreamId; std::string strVhost = info.strVhost; DebugL << "\r\n# record strFileName:\r\n" << strFileName << ":" << strFilePath << "\r\n" << "# strFolder:\r\n" << strFolder << "\r\n"; //启动执行切片的脚本 std::string strcmd = "/usr/local/bin/ffmpeg_mp4_to_hls.sh "+strFileName+" "+strFilePath + " "+strFolder; system(strcmd.c_str()); }); } void main(){ //读camera的配置列表 uint16_t cameranumber = mINI::Instance()[CameraConfig::number]; int i = 0; for (;i<cameranumber; i++) { string ipKey = CameraConfig::ip + to_string(i+1).data(); string url = mINI::Instance()[ipKey]; if (url.size() == 0){ continue; } //bEnableRtsp:false, bEnableRtmp = true, bEnableHls = true, bEnableMp4 = true, PlayerProxy::Ptr player(new PlayerProxy(DEFAULT_VHOST, "live", std::string("chn") + to_string(i+1).data(), false, true, true, true, -1, nullptr)); //指定RTP over TCP(播放rtsp时有效) (*player)[kRtpType] = Rtsp::RTP_TCP; //开始播放,如果播放失败或者播放中止,将会自动重试若干次,重试次数在配置文件中配置,默认一直重试 player->play(url); //需要保存PlayerProxy,否则作用域结束就会销毁该对象 mGlobalProxyMap.emplace(to_string(i), player); } if (mGlobalProxyMap.size() > 0){ startMonitorRecord(); //不需要这个功能了, 录制自动一个小时录制一次 //起一个定时服务,每隔15分钟停止一次录制,然后开启录制 // startRecordTimer(); } // add end } //add end.
修改WebAPI.cpp,增加获取HLS点播地址的功能!
api_regist1("/index/api/getHlsRecordFile", [](API_ARGS1){ CHECK_SECRET(); CHECK_ARGS("vhost", "app", "stream"); auto record_path = Recorder::getRecordPath(Recorder::type_mp4, allArgs["vhost"], allArgs["app"],allArgs["stream"]); auto period = allArgs["period"]; //判断是获取mp4文件列表还是获取文件夹列表 bool search_mp4 = true;//period.size() == sizeof("2020-02-01") - 1; if (search_mp4) { record_path = record_path + period + "/"; } Json::Value paths(arrayValue); //这是筛选日期,获取文件夹列表 File::scanDir(record_path, [&](const string &path, bool isDir) { int pos = path.rfind('/'); if (pos != string::npos) { string relative_path = path.substr(pos + 1); if (search_mp4) { if (!isDir) { //返回m3u8文件路径 std::string file_name = relative_path.substr(0, relative_path.size() - 4); paths.append(file_name+"/" + file_name+".m3u8"); } } else if (isDir && relative_path.find(period) == 0) { //匹配到对应日期的文件夹 paths.append(relative_path); } } return true; }, false); val["data"]["rootPath"] = record_path; val["data"]["paths"] = paths; });
接口返回的数据:
http://192.168.1.120:8090/index/api/getHlsRecordFile?secret=03334667635c73f7-bb6bcc&vhost=__defaultVhost__&app=live&stream=chn2&period=2020-11-16
返回参数:
{"code":0,"data":{"paths":["12-38-59/12-38-59.m3u8","11-39-51/11-39-51.m3u8","11-29-43/11-29-43.m3u8","11-23-29/11-23-29.m3u8","13-09-01/13-09-01.m3u8","12-08-57/12-08-57.m3u8","11-54-47/11-54-47.m3u8"],"rootPath":"/opt/mediaserver/www/record/live/chn1/2020-11-16/"}}
点播视频的地址:http://192.168.1.120:8090/record/live/chn1/2020-11-16/12-38-59/12-38-59.m3u8
录制的视频和切片文件的目录结构关系:
[root@localhost 2020-11-16]# pwd /usr/local/src/server/ZLMediaKit/release/linux/Debug/www/record/live/chn1/2020-11-16 [root@localhost 2020-11-16]# ll 总用量 1054856 -rw-r--r-- 1 root root 38781317 11月 16 11:28 11-23-29.mp4 -rw-r--r-- 1 root root 38710638 11月 16 11:34 11-29-43.mp4 drwxr-xr-x 2 root root 4096 11月 16 11:54 11-39-51 -rw-r--r-- 1 root root 38749464 11月 16 11:44 11-39-51.mp4 drwxr-xr-x 2 root root 4096 11月 16 12:00 11-54-47 -rw-r--r-- 1 root root 38730555 11月 16 11:59 11-54-47.mp4 drwxr-xr-x 2 root root 4096 11月 16 12:40 12-08-57 -rw-r--r-- 1 root root 231337755 11月 16 12:38 12-08-57.mp4 drwxr-xr-x 2 root root 4096 11月 16 13:10 12-38-59 -rw-r--r-- 1 root root 231368491 11月 16 13:09 12-38-59.mp4 drwxr-xr-x 2 root root 4096 11月 16 13:40 13-09-01 -rw-r--r-- 1 root root 231344722 11月 16 13:39 13-09-01.mp4 drwxr-xr-x 2 root root 4096 11月 16 15:13 14-41-54 -rw-r--r-- 1 root root 231089039 11月 16 15:11 14-41-54.mp4 [root@localhost 2020-11-16]#
ffmpeg_mp4_to_hls.sh, mp4视频转HLS脚本的功能:
#!/bin/sh #接收用户参数 strFileName=$1 strFilePath=$2 strFolder=$3 function starttransport(){ #截取除后缀的文件名 hlsFileName=$(echo $strFileName | cut -d . -f1) hlsFolderPath=${strFilePath%"${strFileName}"} hlsFolderPath="${hlsFolderPath}${hlsFileName}/" #create folder. $(mkdir -p ${hlsFolderPath}) echo "hlsFileName:${hlsFileName}, hlsForderPath:${hlsFolderPath}" #$(cd ${hlsFolderPath}) $(ffmpeg -i ${strFilePath} -c:v libx264 -hls_time 60 -hls_list_size 0 -c:a aac -strict -2 -f hls ${hlsFolderPath}${hlsFileName}.m3u8 &) } #main starttransport
-------------------广告线---------------
项目、合作,欢迎勾搭,邮箱:promall@qq.com
本文为呱牛笔记原创文章,转载无需和我联系,但请注明来自呱牛笔记 ,it3q.com