BindUserVideoFrames (Unreal Engine)

- Declaration

static UCavrnusBinding* BindUserVideoFrames(FCavrnusSpaceConnection SpaceConnection, const FCavrnusUser& User, const VideoFrameUpdateFunction& UpdateFrameCallback);

Delegates Options:

DECLARE_DYNAMIC_DELEGATE_OneParam(FCavrnusUserVideoFrameEvent, UTexture2D*, UserVideoFrame);

typedef TFunction<void(UTexture2D*)> VideoFrameUpdateFunction;

- Description

Triggers an event for every new frame of a user’s video stream. Note that this frame will sometimes be null if there is no stream.

The provided type is TextureWithUVs. This is important because different stream sources sometimes provide odd UVRects. For performance reasons we don’t attempt to flip/correct the Textures themselves but instead we provide you with the UVs to flip the top-level UI when necessary. See the sample below for more details.

- Blueprint Sample

BindUserVideoFrames.png
User Video Image Widget

- Code Sample

Sample comes from class UCavrnusUserWidget in the plugin. This widget displays the user’s profile picture or video stream texture.

CavrnusUserWidget.h:

#pragma once #include "CoreMinimal.h" #include <Blueprint/UserWidget.h> #include "Types/CavrnusBinding.h" #include "Types/CavrnusCallbackTypes.h" #include "CavrnusConnectorVideoRequest.h" #include "CavrnusUserWidget.generated.h" class UTexture2D; /** * * Base class for widget representing a Cavrnus User in the UI * */ UCLASS(Abstract) class CAVRNUSCONNECTOR_API UCavrnusUserWidget : public UUserWidget { GENERATED_BODY() virtual void NativeDestruct() override; protected: UFUNCTION(BlueprintCallable, Category = "Cavrnus|UI") void InitializeUserConnection(const FCavrnusSpaceConnection& InSpaceConnection, const FCavrnusUser& InUser); UPROPERTY(BlueprintReadOnly, Category = "Cavrnus", meta = (BindWidget)) class UImage* RtcStreamImage; UPROPERTY(BlueprintReadOnly, Category = "Cavrnus", meta = (BindWidget)) class UImage* ProfileImage; UPROPERTY(BlueprintReadOnly, Category = "Cavrnus") FCavrnusSpaceConnection SpaceConnection; UPROPERTY(BlueprintReadOnly, Category = "Cavrnus") FCavrnusUser User; private: void BindUserVideo(); void UnbindUserVideo(); UFUNCTION() void UpdateVideoTexture(UTexture2D* InTexture); FCavrnusBinding UserVideoFrameBinding; FCavrnusUserVideoFrameEvent UserVideoFrameEvent; };

CavrnusUserWidget.cpp:

#include "UI/CavrnusUserWidget.h" #include <Engine/Texture2D.h> #include <Components/Image.h> #include "CavrnusFunctionLibrary.h" #include "CavrnusConnectorVideoRequest.h" void UCavrnusUserWidget::NativeDestruct() { Super::NativeDestruct(); UnbindUserVideo(); } void UCavrnusUserWidget::InitializeUserConnection(const FCavrnusSpaceConnection& InSpaceConnection, const FCavrnusUser& InUser) { UnbindUserVideo(); SpaceConnection = InSpaceConnection; User = InUser; BindUserVideo(); } void UCavrnusUserWidget::BindUserVideo() { if (!UserVideoFrameEvent.IsBound()) { UserVideoFrameEvent.BindUFunction(this, GET_FUNCTION_NAME_CHECKED(UCavrnusUserWidget, UpdateVideoTexture)); } UserVideoFrameBinding = UCavrnusFunctionLibrary::BindUserVideoFrames(SpaceConnection, User, UserVideoFrameEvent); } void UCavrnusUserWidget::UnbindUserVideo() { if (UserVideoFrameEvent.IsBound()) { UserVideoFrameEvent.Clear(); } if (UserVideoFrameBinding.Unhook) { UserVideoFrameBinding.Unhook(); } } void UCavrnusUserWidget::UpdateVideoTexture(UTexture2D* InTexture) { if (!RtcStreamImage) { return; } if (InTexture) { RtcStreamImage->SetBrushFromTexture(InTexture); } }