danil.klyuev Posted December 23, 2024 Posted December 23, 2024 Добрый день, хотел бы задать всем на форуме такой вопрос. Можно ли использовать API для того, чтобы внешней программой взять видеопоток для своих целей?
arizmenda Posted December 25, 2024 Posted December 25, 2024 Здравствуйте. Видеопотока внутри движка нет. Как вариант - грэбать текстуру в каждом кадре и потом конвертировать в изображение, а дальше делать с массивом пикселей что угодно. Например: Spoiler void VideoFrameCapturer::grabFrame() { auto window = Unigine::WindowManager::getMainWindow(); Unigine::TexturePtr temporary_texture = Unigine::Render::getTemporaryTexture2D( window->getClientRenderSize().x, window->getClientRenderSize().y, Unigine::Texture::FORMAT_RGBA8); temporary_texture->copy2D(); frames.emplace_back(AsyncTransfer::TextureToImage(temporary_texture), rtc::TimeMicros()); Unigine::Render::releaseTemporaryTexture(temporary_texture); } В sendFrame можно писать свою кастомную логику: Spoiler void VideoFrameCapturer::sendFrame() { while (frames.size() > 0 && frames.first().first->completed) { auto v = frames.takeFirst(); auto image = v.first->image; } } На конец кадра подписываемся вот так: Spoiler Unigine::WindowManager::getMainWindow()->getEventFuncEndRender().connect(event_connections, this, &VideoFrameCapturer::grabFrame); Unigine::WindowManager::getMainWindow()->getEventFuncSwap().connect(event_connections, this, &VideoFrameCapturer::sendFrame); А вот сам конвертер текстуры в изображение: Spoiler struct ImageContainer { std::atomic_bool completed = false; Unigine::ImagePtr image; }; UNIGINE_INLINE std::shared_ptr<ImageContainer> TextureToImage(Unigine::TexturePtr texure) { if (!texure) return nullptr; std::shared_ptr<ImageContainer> ret = std::make_shared<ImageContainer>(); std::weak_ptr<ImageContainer> weak = ret; Unigine::Render::asyncTransferTextureToImage(nullptr, Unigine::MakeCallback([weak](const Unigine::ImagePtr &image) { if (std::shared_ptr<ImageContainer> spt = weak.lock()) { spt->image = Unigine::Image::create(); spt->image->swap(image); spt->completed = true; } }), texure); return ret; } 1
danil.klyuev Posted December 25, 2024 Author Posted December 25, 2024 54 minutes ago, arizmenda said: Здравствуйте. Видеопотока внутри движка нет. Как вариант - грэбать текстуру в каждом кадре и потом конвертировать в изображение, а дальше делать с массивом пикселей что угодно. Например: Hide contents void VideoFrameCapturer::grabFrame() { auto window = Unigine::WindowManager::getMainWindow(); Unigine::TexturePtr temporary_texture = Unigine::Render::getTemporaryTexture2D( window->getClientRenderSize().x, window->getClientRenderSize().y, Unigine::Texture::FORMAT_RGBA8); temporary_texture->copy2D(); frames.emplace_back(AsyncTransfer::TextureToImage(temporary_texture), rtc::TimeMicros()); Unigine::Render::releaseTemporaryTexture(temporary_texture); } В sendFrame можно писать свою кастомную логику: Hide contents void VideoFrameCapturer::sendFrame() { while (frames.size() > 0 && frames.first().first->completed) { auto v = frames.takeFirst(); auto image = v.first->image; } } На конец кадра подписываемся вот так: Hide contents Unigine::WindowManager::getMainWindow()->getEventFuncEndRender().connect(event_connections, this, &VideoFrameCapturer::grabFrame); Unigine::WindowManager::getMainWindow()->getEventFuncSwap().connect(event_connections, this, &VideoFrameCapturer::sendFrame); А вот сам конвертер текстуры в изображение: Hide contents struct ImageContainer { std::atomic_bool completed = false; Unigine::ImagePtr image; }; UNIGINE_INLINE std::shared_ptr<ImageContainer> TextureToImage(Unigine::TexturePtr texure) { if (!texure) return nullptr; std::shared_ptr<ImageContainer> ret = std::make_shared<ImageContainer>(); std::weak_ptr<ImageContainer> weak = ret; Unigine::Render::asyncTransferTextureToImage(nullptr, Unigine::MakeCallback([weak](const Unigine::ImagePtr &image) { if (std::shared_ptr<ImageContainer> spt = weak.lock()) { spt->image = Unigine::Image::create(); spt->image->swap(image); spt->completed = true; } }), texure); return ret; } Хотел бы еще уточнить,я не очень силен в С++, поэтому хотел в Python уже обрабатывать необходимое изображение. Подскажите, в данном формате есть ли ссылка, на которую можно будет сослаться для внешнего приложения на Python?
arizmenda Posted December 26, 2024 Posted December 26, 2024 Попробуйте изучить HttpImageResponseSample.cpp в demos\cpp_samples_demo_2.19.1\source\network. Это пример того, как png отправляется из движка в браузер. Можно получить png таким же запросом на Python. Например вот так - get_screen_cmd.py
Recommended Posts