Проблема:
Я хочу реализовать безопасную версию для обработки данных в видео через OpenCV, это должно работать на Windows, Mac и Linux. Данные должны быть сохранены в видеокодеке без потерь.
Сохранение файла под моей текущей настройкой не проблема, и я знаю, что с помощью -1
как fourcc
с videoWriter
появится окно
То, что я не могу гарантировать, — то, что у системы есть способность показать окно вообще! Таким образом, всплывающее меню нормально как запасной вариант, но не как основное решение.
Вопрос:
Есть ли способ проверить с помощью OpenCV, установлен ли на компьютере определенный видеокодек, не сталкиваясь с проблемами компиляции? Что-то вроде:
if (`codec installed`)
int codec = opencvfourcc(codec)
else
int codec = -1
OpenCV использует FFmpeg
декодировать видео файлы. Таким образом, если OpenCV был собран с версией FFmpeg в системе, то мы можем использовать командную строку FFmpeg для проверки доступности нашего выбранного кодека. Для запуска системных команд из C ++ я использовал код из Вот. Эта почта подробно, как проверить тип ОС.
#include <cstdio>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>
#include <array>
#if defined(_WIN32) || defined(_WIN64)
#define OS_WINDOWS
#elif defined(__APPLE__) || defined(__MACH__)
#define OS_OSX
#elif defined(__linux__)
#define OS_LINUX
#endif
std::string exec(const std::string& command ) {
const char* cmd = command.c_str();
std::array<char, 128> buffer;
std::string result;
#if defined(OS_WINDOWS)
std::shared_ptr<FILE> pipe(_popen(cmd, "r"), _pclose);
#elif defined(OS_LINUX) || defined (OS_OSX)
std::shared_ptr<FILE> pipe(popen(cmd, "r"), pclose);
#endif
if (!pipe) throw std::runtime_error("popen() failed!");
while (!feof(pipe.get())) {
if (fgets(buffer.data(), 128, pipe.get()) != nullptr)
result += buffer.data();
}
return result;
}
int main() {
// codec of choice
std::string codec = "H264";
// if OS is linux or OSX then use FFmpeg with grep command
#if defined (OS_LINUX) || defined (OS_OSX)
std::string command = "ffmpeg -codecs | grep -i ";
// if WINDOWS then FFmpeg with findstr
#elif defined (OS_WINDOWS)
std::string command = "ffmpeg -codecs | findstr /i ";
#endif
// execute the system command and get the output
std::string str = exec(command+codec);
// if the output string contains the letters DEV then FFmpeg supports the codec
// D: Decoding supported
// E: Encoding supported
// V: Video codec
std::size_t found = str.find("DEV");
if(found != std::string::npos)
std::cout<<"Codec Found"<<std::endl;
return 0;
}
Других решений пока нет …