Добавьте в ZLMediaKit функцию для автоматического преобразования файлов MP4 в HLS.!
Сервер ZLMediakit поддерживает динамическое добавление камер. Для простоты использования предусмотрена возможность статического добавления камер. Добавьте раздел камеры в файл config.ini:
[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 камера Адресная информация камеры, загруженная по умолчанию. Конфигурация.
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(){
//Читаем список конфигураций камеры
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 ноябрь 16 11:28 11-23-29.mp4
-rw-r--r-- 1 root root 38710638 ноябрь 16 11:34 11-29-43.mp4
drwxr-xr-x 2 root root 4096 ноябрь 16 11:54 11-39-51
-rw-r--r-- 1 root root 38749464 ноябрь 16 11:44 11-39-51.mp4
drwxr-xr-x 2 root root 4096 ноябрь 16 12:00 11-54-47
-rw-r--r-- 1 root root 38730555 ноябрь 16 11:59 11-54-47.mp4
drwxr-xr-x 2 root root 4096 ноябрь 16 12:40 12-08-57
-rw-r--r-- 1 root root 231337755 ноябрь 16 12:38 12-08-57.mp4
drwxr-xr-x 2 root root 4096 ноябрь 16 13:10 12-38-59
-rw-r--r-- 1 root root 231368491 ноябрь 16 13:09 12-38-59.mp4
drwxr-xr-x 2 root root 4096 ноябрь 16 13:40 13-09-01
-rw-r--r-- 1 root root 231344722 ноябрь 16 13:39 13-09-01.mp4
drwxr-xr-x 2 root root 4096 ноябрь 16 15:13 14-41-54
-rw-r--r-- 1 root root 231089039 ноябрь 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