Вопрос

Я должен предоставить своим пользователям действительно простой способ захвата видеоклипов из главного окна моего приложения OpenGL.Я подумываю о добавлении кнопок и/или сочетаний клавиш для запуска и остановки захвата;при запуске я мог запросить имя файла и другие параметры, если таковые имеются.Он должен работать в Windows (XP/Vista), но мне также не хотелось бы закрывать дверь Linux, которую мне до сих пор удавалось держать открытой.

В приложении используются фрагментные и шейдерные программы OpenGL, эффекты благодаря которым мне совершенно необходимы в конечных видеороликах.

Мне кажется, что может быть даже несколько разных подходов, которые потенциально могут удовлетворить мои требования (но я действительно не знаю, с чего мне начать):

  • Библиотека кодирования с такими функциями, как startRecording(имя файла), stopRecording и captureFrame.Я мог бы вызывать captureFrame() после каждого визуализированного кадра (или каждую секунду/третий/что угодно).Если из-за этого моя программа будет работать медленнее, это не проблема.

  • Автономная внешняя программа, которой можно программно управлять из моего приложения.Ведь отдельная программа, которая может нет быть под контролем почти делает то, что мне нужно...Но, как уже было сказано, пользователям должно быть очень просто работать, и я также был бы признателен за плавность работы;мое приложение обычно работает в полноэкранном режиме.Кроме того, должна быть возможность распространяться как часть установочного пакета моего приложения, которое я сейчас готовлю с помощью NSIS.

  • Используйте Windows API для покадрового захвата снимков экрана, а затем используйте (например) один из упомянутые здесь библиотеки.Кажется, достаточно легко найти примеры того, как делать снимки экрана в Windows;однако мне бы хотелось решение, которое не заставило бы меня сильно пачкать руки на уровне WinAPI.

  • Используйте OpenGL для рендеринга в закадровую цель, а затем используйте библиотеку для создания видео.Я не знаю, возможно ли это вообще, и боюсь, что это все равно не путь наименьшей боли.В частности, мне бы не хотелось, чтобы фактический рендеринг выполнялся по-разному в зависимости от того, захватывается видео или нет.Кроме того, я бы избегал всего, что могло бы снизить частоту кадров в обычном режиме без захвата.

Если бы решение было бесплатным в любом смысле этого слова, это было бы здорово, но на самом деле это не является абсолютным требованием.В общем, чем меньше наворотов, тем лучше.С другой стороны, по причинам, выходящим за рамки этого вопроса, я, к сожалению, не могу ссылаться на какой-либо код, предназначенный только для GPL.

Что касается формата файла, я не могу ожидать, что мои пользователи начнут искать в Google какие-либо кодеки, но пока отображение Видео достаточно просто для пользователя Windows базового уровня, мне все равно, какой формат.Однако было бы здорово, если бы можно было контролировать качество сжатия вывода.

Просто для уточнения:я не Мне нужно захватить видео с внешнего устройства, такого как видеокамера, и меня не особо интересуют движения мыши, хотя их получение тоже не повредит.Никаких требований к звуку нет;приложение не издает никакого шума.

Я пишу на C++, используя Visual Studio 2008, и в этом приложении также используются преимущества GLUT и GLUI.У меня есть четкое представление о C++, связывании библиотек и тому подобном, но, с другой стороны, OpenGL для меня совершенно новый:до сих пор я выучил только то, что необходимо для выполнения своей работы.

Решение мне не нужно сверхсрочно, так что не торопитесь :)

Это было полезно?

Решение

Здесь возникает два разных вопроса — как получить кадры из приложения OpenGL и как превратить их в файл фильма.

Первый вопрос достаточно прост;вы просто захватываете каждый кадр с помощью glReadPixels() (через PBO, если вам нужна производительность).

Второй вопрос немного сложнее, поскольку кроссплатформенные решения (ffmpeg), как правило, имеют лицензию GPL или LGPL.Приемлемо ли LGPL для вашего проекта?Способ сделать это в Windows (DirectShow) является своего рода головной болью в использовании.

Редактировать: Поскольку с LGPL все в порядке и вы можете использовать ffmpeg, см. здесь для примера того, как кодировать видео.

Другие советы

Этот выглядит весьма актуальным для слияния с AVI (как предложил Эндрю), однако я действительно надеялся избежать LPBITMAPINFOHEADER и т. д.

Спасибо за ответы, о успехах сообщу, если они будут :)

А пока дополнительные советы по кодированию необработанных кадров из glReadPixels в видеоклипы будут оценены по достоинству.

Редактировать: На данный момент кажется, что ffmpeg, предложенный Майком Ф., является подходящим вариантом.Однако я еще не вник в реальную реализацию, но надеюсь, что в ближайшем будущем это изменится!

Самый простой вариант — сохранить каждый визуализированный кадр из вашего приложения, а затем объединить их в AVI.Если у вас есть AVI, доступно множество библиотек, которые могут преобразовать его в более оптимальный формат или, возможно, вообще пропустить этап AVI.

Что касается получения каждого кадра, вы можете добиться этого либо путем рендеринга в закадровую текстуру, как вы предлагаете, либо напрямую используя обратный буфер в качестве источника, если ваше оборудование поддерживает это.Выполнить любое из этих действий (и сохранить каждый кадр) будет сложно без значительного снижения частоты кадров.

Если ваше приложение является детерминированным, вы можете «записывать» действия пользователей как серию входных данных, а затем использовать режим экспорта, который последовательно отображает их на закадровой поверхности для создания AVI.

Мне пришлось создать демонстрационный проект записи рендеринга OpenGL в видео.я использовал glReadPixels чтобы получить данные пикселей и создать видео с помощью OpenCV cvWriteFrame.OpenCV позволяет писать в формате divx или даже x264/vp8 (со скомпилированным ffmpeg).

В моем блоге есть более подробная запись вместе с примером проекта.http://tommy.chheng.com/2013/09/09/encode-opengl-to-video-with-opencv/

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top