Добавьте в ZLMediaKit функцию для автоматического преобразования файлов MP4 в HLS.
Добавьте в ZLMediaKit функцию для автоматического преобразования файлов MP4 в HLS.

Добавьте в ZLMediaKit функцию для автоматического преобразования файлов MP4 в HLS.!

Сервер ZLMediakit поддерживает динамическое добавление камер. Для простоты использования предусмотрена возможность статического добавления камер. Добавьте раздел камеры в файл config.ini:

Язык кода:javascript
копировать
[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:

Язык кода:javascript
копировать
//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-адреса по требованию!

Язык кода:javascript
копировать
    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

Возвращаемые параметры:

Язык кода:javascript
копировать
{"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

Взаимосвязь структуры каталогов между записанными видео и файлами фрагментов:

Язык кода:javascript
копировать
[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-скрипт:

Язык кода:javascript
копировать
#!/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
boy illustration
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose