给ZLMediaKit添加一个录制MP4文件自动转HLS的功能

给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

呱牛笔记

本文为呱牛笔记原创文章,转载无需和我联系,但请注明来自呱牛笔记 ,it3q.com

请先登录后发表评论
  • 最新评论
  • 总共0条评论