Снимок экрана с игровым видео

8

Я бы хотел «зацепиться» за работающую игру, скажем Mario Bros, и захватить каждый отрендеренный кадр ... сохранив этот кадр в файл изображения. Хорошим примером чего-то подобного является FRAPS. - Примечание: я не хочу снимать весь экран / рабочий стол. Я хочу захватить целевое окно.

Я посмотрел на OBS (Open Broadcasting Software), но это не особенно быстро. Не поймите меня неправильно, это отличное программное обеспечение, но, к сожалению, нет / плохой документации, что делает массивный проект, написанный на c и c ++, практически недоступным для начинающего программиста на c ++.

Я также взглянул на GamingAnywhere , но, к сожалению, я не могу заставить его работать, документации очень мало / нет, она работает только на VS2010 и грязная (с плохим именованием переменных). Тем не менее, это исследовательский проект, и поэтому он по понятным причинам недокументирован и грязен.

Я знаю, что это можно сделать с помощью OpenGL, GDI и Direct3D, но я не могу найти несколько хороших примеров в сети.

Я читал, что можно использовать glReadlPixels (используя OpenGL), и я прочитал документацию , но в посте ничего не упоминалось о подключении к работающей графике игры / приложения.

Вопросов:

  1. Могу ли я подключиться к графике игры, разработанной с помощью OpenGL, используя, скажем, Direct3D? Должна ли библиотека, используемая для перехвата, быть такой же, как библиотека, используемая в игре?

  2. Как подключиться к отображаемым кадрам игры, чтобы я мог выводить эти кадры в файлы изображений или в видеофайл? (Просто несколько ссылок или краткое объяснение того, что мне нужно сделать, было бы здорово)

  3. BackBuffer - я прочитал, что это очень быстрый доступ к BackBuffer для получения кадров. Есть ли у меня пример для меня, как это сделать с последними библиотеками? Я обнаружил, что большинство примеров устарели.

  4. Для моих целей, есть ли какое-то однозначное «это быстрее, чем это»? Что я имею в виду, скажем, OpenGL, будет быстрее для моих целей?

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

Pookie
источник
Теперь, похоже, это только Mac, который может не работать с Direct3D, но Siphon Inject, который OBS использует на Mac, может захватывать игровые окна, использующие OpenGL, намного быстрее, чем стандартный захват видео. Сифон "позволяет приложениям обмениваться кадрами - видео или кадры с полной частотой кадров - друг с другом в режиме реального времени", - цитирует сайт.
планерист
@ Gliderman Спасибо, я проверю это!
Пуки

Ответы:

7

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

Я бы начал изучать методы внедрения DLL , которые должны позволять, например, перехватывать вызовы API-интерфейсов Direct3D (Windows) или OpenGL, которые затем можно использовать для копирования кадровых буферов приложения. Быстрый поиск в Интернете обнаруживает это и это с подробным объяснением.

Однажды я написал небольшой перехватчик OpenGL в MacOS, внедрив пользовательский общий модуль, но он находился в очень контролируемых условиях и делал много предположений, таких как наличие корневых привилегий в системе, поэтому для производственного инструмента это было бы намного сложнее. Вы можете найти еще один очень интересный проект здесь о перехвате D3D API , чтобы установить автоматический бот AI на Starcraft, который должен коснуться на очень похожие понятия, что вы ищете.

Как только вам удастся перехватить базовый API рендеринга, вы можете подключить свой код к каждому SwapBuffersили эквивалентному вызову, чтобы просто скопировать предыдущий кадровый буфер перед свопингом, а затем сохранить его (это то, где что-то подобное glReadPixelsвступает в игру).

Эффективное копирование и сохранение кадрового буфера также является сложной задачей. Самый простой способ - просто записать каждый кадр в виде несжатого RGB-изображения, но тогда вы получите сотни гигабайт данных всего за пару минут игрового процесса, поэтому, если у вас не будет хорошего массива жестких дисков, расположенного на углу ваш стол ;), вам нужно как-то посмотреть на сжатие кадров.

Недостаток сжатия кадров в настоящее время заключается в том, что он требует большой обработки, поэтому наивный подход может превратить некогда интерактивное приложение, которое вы пытаетесь записать, в интерактивное слайд-шоу :(. Так что на этом этапе вы должны начать думать об оптимизации.

Не знаю ни одного проекта, предоставляющего библиотеку для эффективного захвата кадров для игр, но это, безусловно, было бы неплохо! Я думаю, что одна вещь, которая может сдерживать такой проект, состоит в том, как я упоминал в начале, что это очень системно-зависимая вещь, поэтому случаи использования, скорее всего, будут ограничены одной платформой или ОС.

glampert
источник
Спасибо за ответ. Я думаю, что в конечном итоге вместо сохранения изображений я буду транслировать их на удаленный компьютер, поэтому копирование кадрового буфера может оказаться подходящим вариантом. Похоже, у вас достаточно опыта с этим материалом. Можете ли вы расширить какие-либо вопросы, которые я задал? Спасибо за помощь!
Пуки
1
@pookie Эй! Конечно, я могу расширить это. Вы хотите, чтобы я прокомментировал что-то конкретное? Что касается ваших вопросов, я думаю, что 1 и 2 можно сделать с помощью хуков DLL, поэтому обязательно прочитайте ссылки, которые я включил (особенно по поводу Starcraft). 3 и 4 будут зависеть от API, но в OpenGL вы можете начать с glReadPixels и работать оттуда, если обнаружите, что он слишком медленный. Мой опыт заключается в записи кадров из моих собственных игр плюс некотором взломе DLL, сделанном в прошлом, но я никогда не комбинировал оба в попытке записи кадров из стороннего приложения;)
glampert
Спасибо! Я проверил ссылки - инъекция Windows DLL и ссылка на Starcraft (довольно круто) кажутся хорошими отправными точками. Я еще раз взгляну на glReadPixels. По вашему мнению, с кем вам было легче работать, а с чем быстрее: DirectX или OpenGL?
Пуки
@pookie, если у вас есть некоторый опыт программирования, я думаю, что Direct3D будет намного проще в использовании, библиотеки лучше спроектированы. На мой взгляд, у OpenGL тоже могут быть "острые углы" (это исходит от того, кто использует OpenGL больше, чем D3D). D3D только для Windows, так что это может быть негативно для вас, не знаю. С точки зрения производительности, я не думаю, что будет какая-то разница, какую вы используете. Лучший совет, который я могу вам дать: сначала выясните, как заставить его работать, а затем позаботьтесь об оптимизации.
Гламперт
1
Ах, хорошо, если вы знакомы с программированием ООП, то D3D определенно будет проще. OpenGL все процедурный и использует кучу глобальных состояний, это в основном то, что я имел в виду под грубыми краями. Удачи тебе!
гламперт